#
tokens: 65613/50000 1/511 files (page 19/20)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 19 of 20. Use http://codebase.md/fujitsu-ai/mcp-server-for-mas-developments?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .gitattributes
├── .gitignore
├── agents
│   ├── __init__.py
│   ├── AgentInterface
│   │   ├── __init__.py
│   │   ├── Python
│   │   │   ├── __init__.py
│   │   │   ├── agent.py
│   │   │   ├── color.py
│   │   │   ├── config.py
│   │   │   ├── language.py
│   │   │   ├── local_file_handler.py
│   │   │   └── network.py
│   │   └── requirements.txt
│   ├── AgentMonitoring
│   │   ├── ChatBot-Agent Dashboard Example - Grafana.json
│   │   ├── images
│   │   │   ├── Grafana.png
│   │   │   └── Prometheus.png
│   │   ├── IoT-Agent Dashboard Example - Grafana.json
│   │   ├── OpenAI compatible API - Agent Dashboard Example - Grafana.json
│   │   ├── prometheus Example.yml
│   │   └── README.md
│   ├── ChatBotAgent
│   │   ├── __init__.py
│   │   ├── config.json.example
│   │   ├── html
│   │   │   ├── favicon.ico
│   │   │   ├── index_de.html
│   │   │   ├── index.html
│   │   │   ├── Logo_light.svg
│   │   │   ├── start_http_server.ps1
│   │   │   └── start_http_server.sh
│   │   ├── Python
│   │   │   ├── __init__.py
│   │   │   └── chatbot_agent.py
│   │   ├── README.md
│   │   └── requirements.txt
│   ├── IoTAgent
│   │   ├── config_example.json
│   │   ├── Python
│   │   │   ├── iot_mqtt_agent.py
│   │   │   └── language.py
│   │   ├── README.md
│   │   └── requirements.txt
│   ├── ISMAgent
│   │   ├── config_example.json
│   │   ├── PGPT Scenario Prompts
│   │   │   ├── ISM System Prompt - Detecting Error State.txt
│   │   │   ├── ISM User Post-Prompt - Detecting Error State.txt
│   │   │   ├── ISM User Pre-Prompt - Detecting Error State.txt
│   │   │   └── README.md
│   │   ├── Python
│   │   │   ├── ism_agent.py
│   │   │   └── language.py
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── start_ism_agent.ps1
│   ├── MCP-Client
│   │   ├── __init__.py
│   │   ├── .env.example
│   │   ├── Python
│   │   │   ├── __init__.py
│   │   │   ├── chat_handler.py
│   │   │   ├── config.py
│   │   │   ├── environment.py
│   │   │   ├── llm_client.py
│   │   │   ├── mcp_client_sse.py
│   │   │   ├── mcp_client.py
│   │   │   ├── messages
│   │   │   │   ├── __init__.py
│   │   │   │   ├── message_types
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── incrementing_id_message.py
│   │   │   │   │   ├── initialize_message.py
│   │   │   │   │   ├── json_rpc_message.py
│   │   │   │   │   ├── ping_message.py
│   │   │   │   │   ├── prompts_messages.py
│   │   │   │   │   ├── prompts_models.py
│   │   │   │   │   ├── resources_messages.py
│   │   │   │   │   └── tools_messages.py
│   │   │   │   ├── send_call_tool.py
│   │   │   │   ├── send_initialize_message.py
│   │   │   │   ├── send_message.py
│   │   │   │   ├── send_ping.py
│   │   │   │   ├── send_prompts.py
│   │   │   │   ├── send_resources.py
│   │   │   │   └── send_tools_list.py
│   │   │   ├── system_prompt_generator.py
│   │   │   ├── tools_handler.py
│   │   │   └── transport
│   │   │       ├── __init__.py
│   │   │       └── stdio
│   │   │           ├── __init__.py
│   │   │           ├── stdio_client.py
│   │   │           ├── stdio_server_parameters.py
│   │   │           └── stdio_server_shutdown.py
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── server_config.json
│   ├── OpenAI_Compatible_API_Agent
│   │   ├── __init__.py
│   │   ├── docker-compose.yml
│   │   ├── Dockerfile
│   │   ├── pgpt_openai_api_mcp.json.example
│   │   ├── pgpt_openai_api_proxy.json.example
│   │   ├── Python
│   │   │   ├── __init__.py
│   │   │   ├── client_tests
│   │   │   │   ├── __init__.py
│   │   │   │   ├── openai_test_client_structured.py
│   │   │   │   ├── openai_test_client_tools.py
│   │   │   │   ├── openai_test_client.py
│   │   │   │   ├── vllm_client_multimodal.py
│   │   │   │   ├── vllm_client.py
│   │   │   │   ├── vllm_structured.py
│   │   │   │   └── vllm_structured2.py
│   │   │   ├── generate_api_key.py
│   │   │   ├── open_ai_helper.py
│   │   │   ├── openai_compatible_api.py
│   │   │   ├── openai_mcp_api.py
│   │   │   ├── pgpt_api.py
│   │   │   ├── privategpt_api.py
│   │   │   └── vllmproxy.py
│   │   ├── README.md
│   │   └── requirements.txt
│   └── SourceManagerAgent
│       ├── __init__.py
│       ├── config.json.example
│       └── Python
│           ├── __init__.py
│           ├── file_tools
│           │   └── loader_factory.py
│           ├── file_upload_agent.py
│           └── local_db.py
├── clients
│   ├── __init__.py
│   ├── C# .Net
│   │   ├── 1.0 mcp_login
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_login.deps.json
│   │   │   │           ├── mcp_login.dll
│   │   │   │           ├── mcp_login.exe
│   │   │   │           ├── mcp_login.pdb
│   │   │   │           ├── mcp_login.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_login.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_login.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_login.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_login.assets.cache
│   │   │   │   │       ├── mcp_login.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_login.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_login.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_login.csproj.Up2Date
│   │   │   │   │       ├── mcp_login.dll
│   │   │   │   │       ├── mcp_login.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_login.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_login.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_login.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_login.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_login.dll
│   │   │   │   ├── mcp_login.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_login.csproj.nuget.g.props
│   │   │   │   ├── mcp_login.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 1.1 mcp_logout
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_logout.deps.json
│   │   │   │           ├── mcp_logout.dll
│   │   │   │           ├── mcp_logout.exe
│   │   │   │           ├── mcp_logout.pdb
│   │   │   │           ├── mcp_logout.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_logout.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_logout.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_logout.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_logout.assets.cache
│   │   │   │   │       ├── mcp_logout.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_logout.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_logout.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_logout.csproj.Up2Date
│   │   │   │   │       ├── mcp_logout.dll
│   │   │   │   │       ├── mcp_logout.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_logout.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_logout.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_logout.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_logout.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_logout.dll
│   │   │   │   ├── mcp_logout.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_logout.csproj.nuget.g.props
│   │   │   │   ├── mcp_logout.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 2.0 mcp_chat
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_chat.deps.json
│   │   │   │           ├── mcp_chat.dll
│   │   │   │           ├── mcp_chat.exe
│   │   │   │           ├── mcp_chat.pdb
│   │   │   │           ├── mcp_chat.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_chat.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_chat.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_chat.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_chat.assets.cache
│   │   │   │   │       ├── mcp_chat.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_chat.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_chat.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_chat.csproj.Up2Date
│   │   │   │   │       ├── mcp_chat.dll
│   │   │   │   │       ├── mcp_chat.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_chat.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_chat.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_chat.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_chat.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_chat.dll
│   │   │   │   ├── mcp_chat.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_chat.csproj.nuget.g.props
│   │   │   │   ├── mcp_chat.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 2.1 mcp_continue_chat
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_continue_chat.deps.json
│   │   │   │           ├── mcp_continue_chat.dll
│   │   │   │           ├── mcp_continue_chat.exe
│   │   │   │           ├── mcp_continue_chat.pdb
│   │   │   │           ├── mcp_continue_chat.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_continue_chat.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_cont.EF178231.Up2Date
│   │   │   │   │       ├── mcp_continue_chat.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_continue_chat.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_continue_chat.assets.cache
│   │   │   │   │       ├── mcp_continue_chat.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_continue_chat.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_continue_chat.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_continue_chat.dll
│   │   │   │   │       ├── mcp_continue_chat.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_continue_chat.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_continue_chat.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_continue_chat.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_continue_chat.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_continue_chat.dll
│   │   │   │   ├── mcp_continue_chat.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_continue_chat.csproj.nuget.g.props
│   │   │   │   ├── mcp_continue_chat.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 2.2 mcp_get_chat_info
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_get_chat_info.deps.json
│   │   │   │           ├── mcp_get_chat_info.dll
│   │   │   │           ├── mcp_get_chat_info.exe
│   │   │   │           ├── mcp_get_chat_info.pdb
│   │   │   │           ├── mcp_get_chat_info.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── Dokumente - Verknüpfung.lnk
│   │   │   ├── mcp_get_chat_info.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_get_.DFF47B4E.Up2Date
│   │   │   │   │       ├── mcp_get_chat_info.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_get_chat_info.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_get_chat_info.assets.cache
│   │   │   │   │       ├── mcp_get_chat_info.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_get_chat_info.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_get_chat_info.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_get_chat_info.dll
│   │   │   │   │       ├── mcp_get_chat_info.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_get_chat_info.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_get_chat_info.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_get_chat_info.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_get_chat_info.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_get_chat_info.dll
│   │   │   │   ├── mcp_get_chat_info.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_get_chat_info.csproj.nuget.g.props
│   │   │   │   ├── mcp_get_chat_info.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 3.0 mcp_create_source
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_create_source.deps.json
│   │   │   │           ├── mcp_create_source.dll
│   │   │   │           ├── mcp_create_source.exe
│   │   │   │           ├── mcp_create_source.pdb
│   │   │   │           ├── mcp_create_source.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_create_source.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_crea.CB4ED912.Up2Date
│   │   │   │   │       ├── mcp_create_source.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_create_source.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_create_source.assets.cache
│   │   │   │   │       ├── mcp_create_source.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_create_source.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_create_source.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_create_source.dll
│   │   │   │   │       ├── mcp_create_source.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_create_source.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_create_source.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_create_source.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_create_source.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_create_source.dll
│   │   │   │   ├── mcp_create_source.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_create_source.csproj.nuget.g.props
│   │   │   │   ├── mcp_create_source.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 3.1 mcp_get_source
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_get_source.deps.json
│   │   │   │           ├── mcp_get_source.dll
│   │   │   │           ├── mcp_get_source.exe
│   │   │   │           ├── mcp_get_source.pdb
│   │   │   │           ├── mcp_get_source.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_get_source.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_get_.4E61956F.Up2Date
│   │   │   │   │       ├── mcp_get_source.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_get_source.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_get_source.assets.cache
│   │   │   │   │       ├── mcp_get_source.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_get_source.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_get_source.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_get_source.dll
│   │   │   │   │       ├── mcp_get_source.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_get_source.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_get_source.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_get_source.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_get_source.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_get_source.dll
│   │   │   │   ├── mcp_get_source.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_get_source.csproj.nuget.g.props
│   │   │   │   ├── mcp_get_source.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 3.2 mcp_list_sources
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_list_sources.deps.json
│   │   │   │           ├── mcp_list_sources.dll
│   │   │   │           ├── mcp_list_sources.exe
│   │   │   │           ├── mcp_list_sources.pdb
│   │   │   │           ├── mcp_list_sources.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_list_sources.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_list_sources.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_list_sources.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_list_sources.assets.cache
│   │   │   │   │       ├── mcp_list_sources.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_list_sources.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_list_sources.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_list_sources.dll
│   │   │   │   │       ├── mcp_list_sources.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_list_sources.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_list_sources.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_list_sources.pdb
│   │   │   │   │       ├── mcp_list.A720E197.Up2Date
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_list_sources.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_list_sources.dll
│   │   │   │   ├── mcp_list_sources.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_list_sources.csproj.nuget.g.props
│   │   │   │   ├── mcp_list_sources.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 3.3 mcp_edit_source
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_edit_source.deps.json
│   │   │   │           ├── mcp_edit_source.dll
│   │   │   │           ├── mcp_edit_source.exe
│   │   │   │           ├── mcp_edit_source.pdb
│   │   │   │           ├── mcp_edit_source.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_edit_source.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_edit_source.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_edit_source.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_edit_source.assets.cache
│   │   │   │   │       ├── mcp_edit_source.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_edit_source.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_edit_source.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_edit_source.dll
│   │   │   │   │       ├── mcp_edit_source.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_edit_source.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_edit_source.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_edit_source.pdb
│   │   │   │   │       ├── mcp_edit.7303BE3B.Up2Date
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_edit_source.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_edit_source.dll
│   │   │   │   ├── mcp_edit_source.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_edit_source.csproj.nuget.g.props
│   │   │   │   ├── mcp_edit_source.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 3.4 mcp_delete_source
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_delete_source.deps.json
│   │   │   │           ├── mcp_delete_source.dll
│   │   │   │           ├── mcp_delete_source.exe
│   │   │   │           ├── mcp_delete_source.pdb
│   │   │   │           ├── mcp_delete_source.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_delete_source.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_dele.67DD13F9.Up2Date
│   │   │   │   │       ├── mcp_delete_source.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_delete_source.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_delete_source.assets.cache
│   │   │   │   │       ├── mcp_delete_source.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_delete_source.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_delete_source.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_delete_source.dll
│   │   │   │   │       ├── mcp_delete_source.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_delete_source.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_delete_source.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_delete_source.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_delete_source.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_delete_source.dll
│   │   │   │   ├── mcp_delete_source.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_delete_source.csproj.nuget.g.props
│   │   │   │   ├── mcp_delete_source.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 4.0 mcp_list_groups
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_list_groups.deps.json
│   │   │   │           ├── mcp_list_groups.dll
│   │   │   │           ├── mcp_list_groups.exe
│   │   │   │           ├── mcp_list_groups.pdb
│   │   │   │           ├── mcp_list_groups.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_list_groups.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_list_groups.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_list_groups.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_list_groups.assets.cache
│   │   │   │   │       ├── mcp_list_groups.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_list_groups.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_list_groups.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_list_groups.dll
│   │   │   │   │       ├── mcp_list_groups.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_list_groups.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_list_groups.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_list_groups.pdb
│   │   │   │   │       ├── mcp_list.EBD5E0D2.Up2Date
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_list_groups.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_list_groups.dll
│   │   │   │   ├── mcp_list_groups.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_list_groups.csproj.nuget.g.props
│   │   │   │   ├── mcp_list_groups.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 4.1 mcp_store_group
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_store_group.deps.json
│   │   │   │           ├── mcp_store_group.dll
│   │   │   │           ├── mcp_store_group.exe
│   │   │   │           ├── mcp_store_group.pdb
│   │   │   │           ├── mcp_store_group.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_store_group.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_stor.AFB4AA35.Up2Date
│   │   │   │   │       ├── mcp_store_group.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_store_group.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_store_group.assets.cache
│   │   │   │   │       ├── mcp_store_group.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_store_group.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_store_group.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_store_group.dll
│   │   │   │   │       ├── mcp_store_group.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_store_group.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_store_group.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_store_group.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_store_group.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_store_group.dll
│   │   │   │   ├── mcp_store_group.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_store_group.csproj.nuget.g.props
│   │   │   │   ├── mcp_store_group.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 4.2 mcp_delete_group
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_delete_group.deps.json
│   │   │   │           ├── mcp_delete_group.dll
│   │   │   │           ├── mcp_delete_group.exe
│   │   │   │           ├── mcp_delete_group.pdb
│   │   │   │           ├── mcp_delete_group.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_delete_group.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_dele.FE1C6298.Up2Date
│   │   │   │   │       ├── mcp_delete_group.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_delete_group.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_delete_group.assets.cache
│   │   │   │   │       ├── mcp_delete_group.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_delete_group.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_delete_group.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_delete_group.dll
│   │   │   │   │       ├── mcp_delete_group.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_delete_group.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_delete_group.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_delete_group.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_delete_group.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_delete_group.dll
│   │   │   │   ├── mcp_delete_group.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_delete_group.csproj.nuget.g.props
│   │   │   │   ├── mcp_delete_group.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 5.0 mcp_store_user
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_store_user.deps.json
│   │   │   │           ├── mcp_store_user.dll
│   │   │   │           ├── mcp_store_user.exe
│   │   │   │           ├── mcp_store_user.pdb
│   │   │   │           ├── mcp_store_user.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_store_user.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_stor.6C0F0C8A.Up2Date
│   │   │   │   │       ├── mcp_store_user.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_store_user.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_store_user.assets.cache
│   │   │   │   │       ├── mcp_store_user.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_store_user.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_store_user.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_store_user.dll
│   │   │   │   │       ├── mcp_store_user.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_store_user.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_store_user.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_store_user.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_store_user.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_store_user.dll
│   │   │   │   ├── mcp_store_user.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_store_user.csproj.nuget.g.props
│   │   │   │   ├── mcp_store_user.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 5.1 mcp_edit_user
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_edit_user.deps.json
│   │   │   │           ├── mcp_edit_user.dll
│   │   │   │           ├── mcp_edit_user.exe
│   │   │   │           ├── mcp_edit_user.pdb
│   │   │   │           ├── mcp_edit_user.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_edit_user.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_edit_user.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_edit_user.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_edit_user.assets.cache
│   │   │   │   │       ├── mcp_edit_user.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_edit_user.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_edit_user.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_edit_user.dll
│   │   │   │   │       ├── mcp_edit_user.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_edit_user.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_edit_user.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_edit_user.pdb
│   │   │   │   │       ├── mcp_edit.94A30270.Up2Date
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_edit_user.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_edit_user.dll
│   │   │   │   ├── mcp_edit_user.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_edit_user.csproj.nuget.g.props
│   │   │   │   ├── mcp_edit_user.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── 5.2 mcp_delete_user
│   │   │   ├── bin
│   │   │   │   └── Debug
│   │   │   │       └── net9.0
│   │   │   │           ├── mcp_delete_user.deps.json
│   │   │   │           ├── mcp_delete_user.dll
│   │   │   │           ├── mcp_delete_user.exe
│   │   │   │           ├── mcp_delete_user.pdb
│   │   │   │           ├── mcp_delete_user.runtimeconfig.json
│   │   │   │           └── Newtonsoft.Json.dll
│   │   │   ├── mcp_delete_user.csproj
│   │   │   ├── obj
│   │   │   │   ├── Debug
│   │   │   │   │   └── net9.0
│   │   │   │   │       ├── .NETCoreApp,Version=v9.0.AssemblyAttributes.cs
│   │   │   │   │       ├── apphost.exe
│   │   │   │   │       ├── mcp_dele.CEB7E33D.Up2Date
│   │   │   │   │       ├── mcp_delete_user.AssemblyInfo.cs
│   │   │   │   │       ├── mcp_delete_user.AssemblyInfoInputs.cache
│   │   │   │   │       ├── mcp_delete_user.assets.cache
│   │   │   │   │       ├── mcp_delete_user.csproj.AssemblyReference.cache
│   │   │   │   │       ├── mcp_delete_user.csproj.CoreCompileInputs.cache
│   │   │   │   │       ├── mcp_delete_user.csproj.FileListAbsolute.txt
│   │   │   │   │       ├── mcp_delete_user.dll
│   │   │   │   │       ├── mcp_delete_user.GeneratedMSBuildEditorConfig.editorconfig
│   │   │   │   │       ├── mcp_delete_user.genruntimeconfig.cache
│   │   │   │   │       ├── mcp_delete_user.GlobalUsings.g.cs
│   │   │   │   │       ├── mcp_delete_user.pdb
│   │   │   │   │       ├── ref
│   │   │   │   │       │   └── mcp_delete_user.dll
│   │   │   │   │       └── refint
│   │   │   │   │           └── mcp_delete_user.dll
│   │   │   │   ├── mcp_delete_user.csproj.nuget.dgspec.json
│   │   │   │   ├── mcp_delete_user.csproj.nuget.g.props
│   │   │   │   ├── mcp_delete_user.csproj.nuget.g.targets
│   │   │   │   ├── project.assets.json
│   │   │   │   └── project.nuget.cache
│   │   │   └── Program.cs
│   │   ├── Code Archiv
│   │   │   ├── mcp_chat.cs
│   │   │   ├── mcp_continue_chat.cs
│   │   │   ├── mcp_create_source.cs
│   │   │   ├── mcp_delete_group.cs
│   │   │   ├── mcp_delete_source.cs
│   │   │   ├── mcp_delete_user.cs
│   │   │   ├── mcp_edit_source.cs
│   │   │   ├── mcp_edit_user.cs
│   │   │   ├── mcp_get_chat_info.cs
│   │   │   ├── mcp_get_source.cs
│   │   │   ├── mcp_list_groups.cs
│   │   │   ├── mcp_list_sources.cs
│   │   │   ├── mcp_login.cs
│   │   │   ├── mcp_logout.cs
│   │   │   ├── mcp_store_group.cs
│   │   │   └── mcp_store_user.cs
│   │   └── README.md
│   ├── C++
│   │   ├── .vscode
│   │   │   └── launch.json
│   │   ├── 1.0 mcp_login
│   │   │   ├── MCPLoginClient.cpp
│   │   │   └── Non-TLS version
│   │   │       ├── MCPLoginClient.cpp
│   │   │       └── MCPLoginClient.exe
│   │   ├── 1.1 mcp_logout
│   │   │   ├── MCPLogoutClient.cpp
│   │   │   └── MCPLogoutClient.exe
│   │   ├── 2.0 mcp_chat
│   │   │   ├── MCPChatClient.cpp
│   │   │   └── MCPChatClient.exe
│   │   ├── 2.1 mcp_continue_chat
│   │   │   ├── MCPChatContinuationClient.cpp
│   │   │   └── MCPChatContinuationClient.exe
│   │   ├── 2.2 mcp_get_chat_info
│   │   │   ├── MCPGetChatInfoClient.cpp
│   │   │   └── MCPGetChatInfoClient.exe
│   │   ├── 3.0 mcp_create_source
│   │   │   ├── MCPCreateSourceClient.cpp
│   │   │   └── MCPCreateSourceClient.exe
│   │   ├── 3.1 mcp_get_source
│   │   │   ├── MCPGetSourceClient.cpp
│   │   │   └── MCPGetSourceClient.exe
│   │   ├── 3.2 mcp_list_sources
│   │   │   ├── MCPListSourcesClient.cpp
│   │   │   └── MCPListSourcesClient.exe
│   │   ├── 3.3 mcp_edit_source
│   │   │   ├── MCPEditSourceClient.cpp
│   │   │   └── MCPEditSourceClient.exe
│   │   ├── 3.4 mcp_delete_source
│   │   │   ├── MCPDeleteSourceClient.cpp
│   │   │   └── MCPDeleteSourceClient.exe
│   │   ├── 4.0 mcp_list_groups
│   │   │   ├── MCPListGroupsClient.cpp
│   │   │   └── MCPListGroupsClient.exe
│   │   ├── 4.1 mcp_store_group
│   │   │   ├── MCPStoreGroupClient.cpp
│   │   │   └── MCPStoreGroupClient.exe
│   │   ├── 4.2 mcp_delete_group
│   │   │   ├── MPCDeleteGroupClient.cpp
│   │   │   └── MPCDeleteGroupClient.exe
│   │   ├── 5.0 mcp_store_user
│   │   │   ├── MCPStoreUserClient.cpp
│   │   │   └── MCPStoreUserClient.exe
│   │   ├── 5.1 mcp_edit_user
│   │   │   ├── MCPEditUserClient.cpp
│   │   │   └── MCPEditUserClient.exe
│   │   ├── 5.2 mcp_delete_user
│   │   │   ├── MCPDeleteUserClient.cpp
│   │   │   └── MCPDeleteUserClient.exe
│   │   ├── 9.0 mcp_keygen
│   │   │   ├── MCPKeygenClient.cpp
│   │   │   └── MCPKeygenClient.exe
│   │   └── README.md
│   ├── Go
│   │   ├── 1.0 mcp_login
│   │   │   ├── go.mod
│   │   │   ├── MCPLoginClient.exe
│   │   │   └── MCPLoginClient.go
│   │   ├── 1.1 mcp_logout
│   │   │   ├── MCPLogoutClient.exe
│   │   │   └── MCPLogoutClient.go
│   │   ├── 2.0 mcp_chat
│   │   │   ├── MCPChatClient.exe
│   │   │   └── MCPChatClient.go
│   │   ├── 2.1 mcp_continue_chat
│   │   │   ├── MCPChatContinuationClient.exe
│   │   │   └── MCPChatContinuationClient.go
│   │   ├── 2.2 mcp_get_chat_info
│   │   │   ├── MCPGetChatInfoClient.exe
│   │   │   └── MCPGetChatInfoClient.go
│   │   ├── 3.0 mcp_create_source
│   │   │   ├── MCPCreateSourceClient.exe
│   │   │   └── MCPCreateSourceClient.go
│   │   ├── 3.1 mcp_get_source
│   │   │   ├── MCPGetSourceClient.exe
│   │   │   └── MCPGetSourceClient.go
│   │   ├── 3.2 mcp_list_sources
│   │   │   ├── MCPListSourcesClient.exe
│   │   │   └── MCPListSourcesClient.go
│   │   ├── 3.3 mcp_edit_source
│   │   │   ├── MCPEditSourceClient.exe
│   │   │   └── MCPEditSourceClient.go
│   │   ├── 3.4 mcp_delete_source
│   │   │   ├── MCPDeleteSourceClient.exe
│   │   │   └── MCPDeleteSourceClient.go
│   │   ├── 4.0 mcp_list_groups
│   │   │   ├── MCPListGroupsClient.exe
│   │   │   └── MCPListGroupsClient.go
│   │   ├── 4.1 mcp_store_group
│   │   │   ├── MCPStoreGroupClient.exe
│   │   │   └── MCPStoreGroupClient.go
│   │   ├── 4.2 mcp_delete_group
│   │   │   ├── MCPDeleteGroupClient.exe
│   │   │   └── MCPDeleteGroupClient.go
│   │   ├── 5.0 mcp_store_user
│   │   │   ├── MCPStoreUserClient.exe
│   │   │   └── MCPStoreUserClient.go
│   │   ├── 5.1 mcp_edit_user
│   │   │   ├── MCPEditUserClient.exe
│   │   │   └── MCPEditUserClient.go
│   │   ├── 5.2 mcp_delete_user
│   │   │   ├── MCPDeleteUserClient.exe
│   │   │   └── MCPDeleteUserClient.go
│   │   ├── 9.0 mcp_keygen
│   │   │   ├── MCPKeygenClient.exe
│   │   │   └── MCPKeygenClient.go
│   │   └── README.md
│   ├── Gradio
│   │   ├── Api.py
│   │   ├── config.json.example
│   │   ├── config.py
│   │   ├── favicon.ico
│   │   ├── file_tools
│   │   │   └── loader_factory.py
│   │   ├── language.py
│   │   ├── logos
│   │   │   ├── fsas.png
│   │   │   └── Logo_dark.svg
│   │   ├── main.py
│   │   ├── mcp_client.py
│   │   ├── mcp_servers
│   │   │   ├── arxiv
│   │   │   │   ├── arxiv-stdio.js
│   │   │   │   ├── package.json
│   │   │   │   ├── README.md
│   │   │   │   ├── requirements.txt
│   │   │   │   └── server_config.example.json
│   │   │   ├── demo-mcp-server
│   │   │   │   ├── demo-tools-sse.js
│   │   │   │   ├── demo-tools-stdio.js
│   │   │   │   └── tools
│   │   │   │       ├── assets.js
│   │   │   │       ├── calculator.js
│   │   │   │       └── weather.js
│   │   │   ├── filesystem
│   │   │   │   ├── Dockerfile
│   │   │   │   ├── index.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── README.md
│   │   │   │   ├── test
│   │   │   │   │   └── new.txt
│   │   │   │   └── tsconfig.json
│   │   │   ├── moondream
│   │   │   │   └── server.py
│   │   │   ├── pgpt
│   │   │   │   ├── __init__.py
│   │   │   │   ├── Api.py
│   │   │   │   ├── config.json.example
│   │   │   │   ├── config.py
│   │   │   │   ├── language.py
│   │   │   │   ├── pyproject.toml
│   │   │   │   ├── README.md
│   │   │   │   └── server.py
│   │   │   ├── replicate_flux
│   │   │   │   └── server.py
│   │   │   └── sqlite
│   │   │       ├── .python-version
│   │   │       ├── Dockerfile
│   │   │       ├── pyproject.toml
│   │   │       ├── README.md
│   │   │       └── src
│   │   │           └── mcp_server_sqlite
│   │   │               ├── __init__.py
│   │   │               └── server.py
│   │   ├── messages
│   │   │   ├── __init__.py
│   │   │   ├── message_types
│   │   │   │   ├── __init__.py
│   │   │   │   ├── incrementing_id_message.py
│   │   │   │   ├── initialize_message.py
│   │   │   │   ├── json_rpc_message.py
│   │   │   │   ├── ping_message.py
│   │   │   │   ├── prompts_messages.py
│   │   │   │   ├── prompts_models.py
│   │   │   │   ├── resources_messages.py
│   │   │   │   └── tools_messages.py
│   │   │   ├── send_call_tool.py
│   │   │   ├── send_initialize_message.py
│   │   │   ├── send_message.py
│   │   │   ├── send_ping.py
│   │   │   ├── send_prompts.py
│   │   │   ├── send_resources.py
│   │   │   └── send_tools_list.py
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   ├── server_config.json
│   │   ├── SourceManagement.py
│   │   ├── transport
│   │   │   ├── __init__.py
│   │   │   └── stdio
│   │   │       ├── __init__.py
│   │   │       ├── stdio_client.py
│   │   │       ├── stdio_server_parameters.py
│   │   │       └── stdio_server_shutdown.py
│   │   ├── tsconfig.json
│   │   └── UserManagement.py
│   ├── Java
│   │   ├── 1.0 mcp_login
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPLoginClient.class
│   │   │   └── MCPLoginClient.java
│   │   ├── 1.1 mcp_logout
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPLogoutClient.class
│   │   │   └── MCPLogoutClient.java
│   │   ├── 2.0 mcp_chat
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPChatClient.class
│   │   │   └── MCPChatClient.java
│   │   ├── 2.1 mcp_continue_chat
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPContinueChatClient.class
│   │   │   └── MCPContinueChatClient.java
│   │   ├── 2.2 mcp_get_chat_info
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPGetChatInfoClient.class
│   │   │   └── MCPGetChatInfoClient.java
│   │   ├── 3.0 mcp_create_source
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPCreateSourceClient.class
│   │   │   └── MCPCreateSourceClient.java
│   │   ├── 3.1 mcp_get_source
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPGetSourceClient.class
│   │   │   └── MCPGetSourceClient.java
│   │   ├── 3.2 mcp_list_sources
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPListSourcesClient.class
│   │   │   └── MCPListSourcesClient.java
│   │   ├── 3.3 mcp_edit_source
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPEditSourceClient.class
│   │   │   └── MCPEditSourceClient.java
│   │   ├── 3.4 mcp_delete_source
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPDeleteSourceClient.class
│   │   │   └── MCPDeleteSourceClient.java
│   │   ├── 4.0 mcp_list_groups
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPListGroupsClient.class
│   │   │   └── MCPListGroupsClient.java
│   │   ├── 4.1 mcp_store_group
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPStoreGroupClient.class
│   │   │   └── MCPStoreGroupClient.java
│   │   ├── 4.2 mcp_delete_group
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPDeleteGroupClient.class
│   │   │   └── MCPDeleteGroupClient.java
│   │   ├── 5.0 mcp_store_user
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPStoreUserClient.class
│   │   │   └── MCPStoreUserClient.java
│   │   ├── 5.1 mcp_edit_user
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPEditUserClient.class
│   │   │   └── MCPEditUserClient.java
│   │   ├── 5.2 mcp_delete_user
│   │   │   ├── json-20241224.jar
│   │   │   ├── MCPDeleteUserClient.class
│   │   │   └── MCPDeleteUserClient.java
│   │   └── README.md
│   ├── JavaScript
│   │   ├── 1.0 mcp_login
│   │   │   └── MCPLoginClient.js
│   │   ├── 1.1 mcp_logout
│   │   │   └── MCPLogoutClient.js
│   │   ├── 2.0 mcp_chat
│   │   │   └── MCPChatClient.js
│   │   ├── 2.1 mcp_continue_chat
│   │   │   └── MCPContinueChatClient.js
│   │   ├── 2.2 mcp_get_chat_info
│   │   │   └── MCPGetChatInfoClient.js
│   │   ├── 3.0 mcp_create_source
│   │   │   └── MCPCreateSourceClient.js
│   │   ├── 3.1 mcp_get_source
│   │   │   └── MCPGetSourceClient.js
│   │   ├── 3.2 mcp_list_sources
│   │   │   └── MCPListSourcesClient.js
│   │   ├── 3.3 mcp_edit_source
│   │   │   └── MCPEditSourceClient.js
│   │   ├── 3.4 mcp_delete_source
│   │   │   └── MCPDeleteSourceClient.js
│   │   ├── 4.0 mcp_list_groups
│   │   │   └── MCPListGroupsClient.js
│   │   ├── 4.1 mcp_store_group
│   │   │   └── MCPStoreGroupClient.js
│   │   ├── 4.2 mcp_delete_group
│   │   │   └── MCPDeleteGroupClient.js
│   │   ├── 5.0 mcp_store_user
│   │   │   └── MCPStoreUserClient.js
│   │   ├── 5.1 mcp_edit_user
│   │   │   └── MCPEditUserClient.js
│   │   ├── 5.2 mcp_delete_user
│   │   │   └── MCPDeleteUserClient.js
│   │   ├── 9.0 mcp_keygen
│   │   │   └── MCPKeygenClient.js
│   │   └── README.md
│   ├── PHP
│   │   ├── 1.0 mcp_login
│   │   │   └── MCPLoginClient.php
│   │   ├── 1.1 mcp_logout
│   │   │   └── MCPLogoutClient.php
│   │   ├── 2.0 mcp_chat
│   │   │   └── MCPChatClient.php
│   │   ├── 2.1 mcp_continue_chat
│   │   │   └── MCPContinueChatClient.php
│   │   ├── 2.2 mcp_get_chat_info
│   │   │   └── MCPGetChatInfoClient.php
│   │   ├── 3.0 mcp_create_source
│   │   │   └── MCPCreateSourceClient.php
│   │   ├── 3.1 mcp_get_source
│   │   │   └── MCPGetSourceClient.php
│   │   ├── 3.2 mcp_list_sources
│   │   │   └── MCPListSourcesClient.php
│   │   ├── 3.3 mcp_edit_source
│   │   │   └── MCPEditSourceClient.php
│   │   ├── 3.4 mcp_delete_source
│   │   │   └── MCPDeleteSourceClient.php
│   │   ├── 4.0 mcp_list_groups
│   │   │   └── MCPListGroupsClient.php
│   │   ├── 4.1 mcp_store_group
│   │   │   └── MCPStoreGroupClient.php
│   │   ├── 4.2 mcp_delete_group
│   │   │   └── MCPDeleteGroupClient.php
│   │   ├── 5.0 mcp_store_user
│   │   │   └── MCPStoreUserClient.php
│   │   ├── 5.1 mcp_edit_user
│   │   │   └── MCPEditUserClient.php
│   │   ├── 5.2 mcp_delete_user
│   │   │   └── MCPDeleteUserClient.php
│   │   ├── 9.0 mcp_keygen
│   │   │   └── MCPKeygenClient.php
│   │   └── README.md
│   └── Python
│       ├── __init__.py
│       ├── 1.0 mcp_login
│       │   └── MCPLoginClient.py
│       ├── 1.1 mcp_logout
│       │   └── MCPLogoutClient.py
│       ├── 2.0 mcp_chat
│       │   └── MCPChatClient.py
│       ├── 2.1 mcp_continue_chat
│       │   └── MCPContinueChatClient.py
│       ├── 2.2 mcp_get_chat_info
│       │   └── MCPGetChatInfoClient.py
│       ├── 2.3 mcp_delete_all_chats
│       │   └── MCPDeleteAllChatsClient.py
│       ├── 2.4 mcp_delete_chat
│       │   └── MCPDeleteChatClient.py
│       ├── 3.0 mcp_create_source
│       │   └── MCPCreateSourceClient.py
│       ├── 3.1 mcp_get_source
│       │   └── MCPGetSourceClient.py
│       ├── 3.2 mcp_list_sources
│       │   └── MCPListSourcesClient.py
│       ├── 3.3 mcp_edit_source
│       │   └── MCPEditSourceClient.py
│       ├── 3.4 mcp_delete_source
│       │   └── MCPDeleteSourceClient.py
│       ├── 4.0 mcp_list_groups
│       │   └── MCPListGroupsClient.py
│       ├── 4.1 mcp_store_group
│       │   └── MCPStoreGroupClient.py
│       ├── 4.2 mcp_delete_group
│       │   └── MCPDeleteGroupClient.py
│       ├── 5.0 mcp_store_user
│       │   └── MCPStoreUserClient.py
│       ├── 5.1 mcp_edit_user
│       │   └── MCPEditUserClient.py
│       ├── 5.2 mcp_delete_user
│       │   └── MCPDeleteUserClient.py
│       ├── 9.0 mcp_keygen
│       │   └── MCPKeygenClient.py
│       ├── Gradio
│       │   ├── __init__.py
│       │   └── server_config.json
│       └── README.md
├── examples
│   ├── create_users_from_csv
│   │   ├── config.json.example
│   │   ├── config.py
│   │   ├── create_users_from_csv.py
│   │   └── language.py
│   ├── dynamic_sources
│   │   └── rss_reader
│   │       ├── Api.py
│   │       ├── config.json.example
│   │       ├── config.py
│   │       ├── demo_dynamic_sources.py
│   │       └── rss_parser.py
│   ├── example_users_to_add_no_tz.csv
│   └── sftp_upload_with_id
│       ├── Api.py
│       ├── config_ftp.json.example
│       ├── config.py
│       ├── demo_upload.py
│       ├── language.py
│       └── requirements.txt
├── images
│   ├── alternative mcp client.png
│   ├── favicon
│   │   ├── android-chrome-192x192.png
│   │   ├── android-chrome-512x512.png
│   │   ├── apple-touch-icon.png
│   │   ├── favicon-16x16.png
│   │   ├── favicon-32x32.png
│   │   ├── favicon.ico
│   │   └── site.webmanifest
│   ├── mcp-general-architecture.png
│   ├── privateGPT-MCP.png
│   └── privateGPT.png
├── InstallMPCServer.sh
├── jest.config.js
├── LICENSE
├── package.json
├── pgpt.env.json.example
├── README.md
├── security
│   ├── generate_decrypted_password.js
│   └── generate_encrypted_password.js
├── src
│   ├── helper.js
│   ├── index.js
│   ├── logger.js
│   ├── pgpt-messages.js
│   ├── public
│   │   ├── index.html
│   │   └── pgpt-mcp-logo.png
│   ├── services
│   │   └── pgpt-service.ts
│   └── types
│       └── api.ts
├── start_chatbot_agent.ps1
├── start_chatbot_agent.sh
├── start_iot_agent.ps1
├── start_iot_agent.sh
├── start_openai_compatible_api_agent.ps1
├── start_openai_compatible_api_agent.sh
├── tsconfig.json
├── ver
│   ├── index_np.js
│   └── index_proxy_np.js
└── WORKLOG.md
```

# Files

--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------

```javascript
   1 | #!/usr/bin/env node
   2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js';
   3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
   4 | import {
   5 |     CallToolRequestSchema,
   6 |     ErrorCode,
   7 |     ListResourcesRequestSchema,
   8 |     ListResourceTemplatesRequestSchema,
   9 |     ListToolsRequestSchema,
  10 |     McpError,
  11 |     ReadResourceRequestSchema
  12 | } from '@modelcontextprotocol/sdk/types.js';
  13 | import axios from 'axios';
  14 | import https from 'https';
  15 | import dotenv from 'dotenv';    
  16 | import net from 'net';
  17 | import { fileURLToPath } from 'url';
  18 | import path from 'path';
  19 | import fs from 'fs';
  20 | import os from 'os';
  21 | import crypto from 'crypto';
  22 | import moment from 'moment'; // Optional: Entfernen, wenn nicht benötigt
  23 | import { prefixMessages, messages } from './pgpt-messages.js';
  24 | import { logEvent, setAllowWrittenLogfile, LOG_FILE_PATH } from './logger.js'; 
  25 | import figlet from 'figlet';
  26 | import chalk from 'chalk';
  27 | import { promisify } from 'util';
  28 | import express from 'express';
  29 | import { createServer as createHttpServer } from 'http';
  30 | import { Server as SocketIoServer } from 'socket.io';
  31 | import chokidar from 'chokidar';
  32 | import stripAnsi from 'strip-ansi';
  33 | import tls from 'tls';
  34 | 
  35 | 
  36 | // Promisifizieren von figlet.text für die Verwendung mit async/await
  37 | const figletAsync = promisify(figlet.text);
  38 | 
  39 | dotenv.config({ path: './pgpt.env' }); // Geben Sie explizit den Pfad zur Datei an
  40 | 
  41 | // JSON-Datei laden
  42 | // `__dirname`-Ersatz für ES-Module
  43 | const __filename = fileURLToPath(import.meta.url);
  44 | const __dirname = path.dirname(__filename);
  45 | 
  46 | // JSON-Dateipfad relativ zum Skript
  47 | const envFilePath = path.resolve(__dirname, '../pgpt.env.json');
  48 | let envConfig;
  49 | 
  50 | try {
  51 |     envConfig = JSON.parse(fs.readFileSync(envFilePath, 'utf-8'));
  52 | } catch (error) {
  53 |     logEvent('system', 'conf', 'Env Load Err', error.message, 'error');
  54 |     process.exit(1);
  55 | }
  56 | 
  57 | // Helper-Funktionen
  58 | function getEnvVar(key, nestedPath = null, fallback = null) {
  59 |     // Prüfen, ob ein verschachtelter Pfad angegeben ist
  60 |     if (nestedPath) {
  61 |         const value = nestedPath.reduce((acc, part) => acc && acc[part], envConfig);
  62 |         if (value === undefined || value === null) {
  63 |             if (fallback !== null) return fallback;
  64 |             logEvent(
  65 |                 'system',
  66 |                 'conf',
  67 |                 'Missing Config',
  68 |                 `Missing .json configuration variable: ${key}`,
  69 |                 'error'
  70 |             );
  71 |             process.exit(1);
  72 |         }
  73 |         return value;
  74 |     }
  75 |     // Direkter Zugriff
  76 |     if (envConfig[key] === undefined || envConfig[key] === null) {
  77 |         if (fallback !== null) return fallback;
  78 |         logEvent(
  79 |             'system',
  80 |             'conf',
  81 |             'Missing Config',
  82 |             `Missing .json configuration variable: ${key}`,
  83 |             'error'
  84 |         );
  85 |         process.exit(1);
  86 |     }
  87 |     return envConfig[key];
  88 | }
  89 | 
  90 | // Nachrichten basierend auf Sprache
  91 | let lang = getEnvVar('LANGUAGE', ['Server_Config', 'LANGUAGE'], 'en').toLowerCase();
  92 | if (!(lang in messages)) {
  93 |     logEvent('system', 'conf', 'Lang Warning', `Language "${lang}" is not supported. Fallback in English.`, 'warn');
  94 |     lang = 'en';
  95 | }
  96 | 
  97 | const t = messages[lang];
  98 | const l = prefixMessages[lang];
  99 | 
 100 | /**
 101 |  * Funktion zum Anzeigen des Startheaders
 102 |  */
 103 | function displayStartHeader() {
 104 |     // Generiere ASCII-Art
 105 |     figlet.text('Fujitsu PGPT MCP-Server', {
 106 |         font: 'Slant', // Schriftart, kann angepasst werden
 107 |         horizontalLayout: 'default',
 108 |         verticalLayout: 'default',
 109 |         width: 80,
 110 |         whitespaceBreak: true
 111 |     }, function(err, data) {
 112 |         if (err) {
 113 |             logEvent('system', 'CLI', l.prefix_Env_Load_Err, t.errorCreatingAsciiArt, 'error');
 114 |             console.dir(err);
 115 |             return;
 116 |         }
 117 |         // Farbige Ausgabe mit Chalk
 118 |         console.log(
 119 |             chalk.green.bold(data) + '\n' +
 120 |             chalk.blue(`${t.mcpVersion} 2.1.0\n`) +
 121 |             chalk.yellow(`${t.mcpPort} ${Port}\n`) +
 122 |             chalk.cyan(`${t.mcpStartTime} ${new Date().toLocaleString()}\n`) +
 123 |             chalk.magenta(`${t.mcpLicense} MIT`)
 124 |         );
 125 |     });
 126 | }
 127 | 
 128 | const privateApiUrl         = getEnvVar('PRIVATE_GPT_API_URL', ['PGPT_Url', 'PRIVATE_GPT_API_URL']);
 129 | const requestedLang         = getEnvVar('LANGUAGE', ['Server_Config', 'LANGUAGE'], 'en').toLowerCase();
 130 | const apiUrl                = getEnvVar('API_URL', ['PGPT_Url', 'API_URL']);
 131 | const Port                  = getEnvVar('PORT', ['Server_Config', 'PORT'], '5000');
 132 | const restrictedGroups      = getEnvVar('RESTRICTED_GROUPS', ['Restrictions', 'RESTRICTED_GROUPS'], 'false').toString();
 133 | const OpenAICompAPI         = getEnvVar('ENABLE_OPEN_AI_COMP_API', ['Restrictions', 'ENABLE_OPEN_AI_COMP_API'], 'false').toString();
 134 | const sslValidate           = getEnvVar('SSL_VALIDATE', ['Server_Config', 'SSL_VALIDATE'], 'false').toString();
 135 | const enableTLS             = getEnvVar('ENABLE_TLS', ['Server_Config', 'ENABLE_TLS'], 'false').toLowerCase() === 'true';
 136 | const PwEncryption          = getEnvVar('PW_ENCRYPTION', ['Server_Config', 'PW_ENCRYPTION'], 'false') === 'true';
 137 | const AllowKeygen           = getEnvVar('ALLOW_KEYGEN', ['Server_Config', 'ALLOW_KEYGEN'], 'false') === 'true';
 138 | const allowWrittenLogfile   = getEnvVar('WRITTEN_LOGFILE', ['Logging', 'WRITTEN_LOGFILE'], 'false').toString();
 139 | const LogIps                = getEnvVar('LOG_IPs', ['Logging', 'LOG_IPs'], 'false').toString();
 140 | const anonymousMode         = getEnvVar('ANONYMOUS_MODE', ['Logging', 'ANONYMOUS_MODE'], 'false').toString();
 141 | 
 142 | // Funktion zur Pfad-Expansion
 143 | function expandPath(filePath) {
 144 |     if (filePath.startsWith('~')) {
 145 |         return path.join(os.homedir(), filePath.slice(1));
 146 |     }
 147 |     return filePath;
 148 | }
 149 | 
 150 | // Load the public key
 151 | const publicKeyPath     = expandPath(getEnvVar('PUBLIC_KEY',    ['Server_Config', 'PUBLIC_KEY']));
 152 | const privateKeyPath    = expandPath(getEnvVar('PRIVATE_KEY',   ['Server_Config', 'PRIVATE_KEY']));
 153 | 
 154 | const sslKeyPath        = expandPath(getEnvVar('SSL_KEY_PATH',  ['Server_Config', 'SSL_KEY_PATH'])); 
 155 | const sslCertPath       = expandPath(getEnvVar('SSL_CERT_PATH', ['Server_Config', 'SSL_CERT_PATH'])); 
 156 | 
 157 | let publicKey;
 158 | let privateKey;
 159 | 
 160 | try {
 161 |     publicKey = fs.readFileSync(publicKeyPath, 'utf8');
 162 |     privateKey = fs.readFileSync(privateKeyPath, 'utf8');
 163 |     logEvent('system', 'conf', l.prefix_Public_API_URL, publicKey, 'info'); // Möglicherweise hier ein anderer Prefix benötigt
 164 |     logEvent('system', 'conf', l.prefix_Private_API_URL, privateKey, 'info'); // Möglicherweise hier ein anderer Prefix benötigt
 165 | } catch (error) {
 166 |     logEvent('system', 'conf', l.prefix_File_Path, error.path, 'error');
 167 |     logEvent('system', 'conf', l.prefix_Env_Load_Err, error.message, 'error');
 168 |     process.exit(1); // Abbrechen, falls Schlüssel nicht geladen werden können
 169 | }
 170 | 
 171 | if (PwEncryption) {
 172 |     logEvent('system', 'conf', l.prefix_PW_Encryption, t.passwordEncEnabled, 'info');
 173 | } else {
 174 |     logEvent('system', 'conf', l.prefix_PW_Encryption, t.passwordEncDisabled, 'info');
 175 | }
 176 | 
 177 | function validateUrl(url, t) {
 178 |     if (!url.startsWith('https://')) {
 179 |         logEvent('system', 'conf', l.prefix_URL_Warning, t.apiUrlWarning, 'warn');
 180 |         url = url.replace(/^http:\/\//, 'https://');
 181 |     }
 182 |     url = url.replace(/([^:]\/)\/+/g, '$1'); // Doppelte Schrägstriche nach "://" entfernen
 183 |     if (!url.endsWith('/api/v1')) {
 184 |         logEvent('system', 'conf', l.prefix_URL_Warning_V1, t.apiUrlWarningV1, 'warn');
 185 |         url = `${url.replace(/\/$/, '')}/api/v1`;
 186 |     }
 187 |     try {
 188 |         new URL(url);
 189 |     } catch {
 190 |         logEvent('system', 'conf', l.prefix_URL_Invalid, `${t.apiUrlInvalid} ${url}`, 'error');
 191 |         process.exit(1);
 192 |     }
 193 |     return url;
 194 | }
 195 | 
 196 | function validatePort(port, t) {
 197 |     const portNumber = parseInt(port, 10);
 198 |     if (isNaN(portNumber) || portNumber < 1 || portNumber > 65535) {
 199 |         logEvent('system', 'conf', l.prefix_Port_Invalid, t.portInvalid, 'error');
 200 |         process.exit(1);
 201 |     }
 202 |     return portNumber;
 203 | }
 204 | 
 205 | function validateBoolean(varName, value, t, useProxy = false) {
 206 |     if (useProxy && (varName === 'HEADER_ENCRYPTED')) {
 207 |         if (value !== 'true' && value !== 'false') {
 208 |             logEvent('system', 'conf', l.prefix_Validation_Err,
 209 |                 t.validationError.replace('${var}', varName).replace('${value}', value), 'error');
 210 |             process.exit(1);
 211 |         }
 212 |         return value === 'true';
 213 |     }
 214 |     // Allgemeine Validierung
 215 |     if (value !== 'true' && value !== 'false') {
 216 |         logEvent('system', 'conf', l.prefix_Validation_Err,
 217 |             t.validationError.replace('${var}', varName).replace('${value}', value), 'error');
 218 |         process.exit(1);
 219 |     }
 220 |     return value === 'true';
 221 | }
 222 | 
 223 | /**
 224 |  * Decrypt a cryptographic string using the private key.
 225 |  * @param {string} encryptedData - The encrypted string in Base64 format.
 226 |  * @returns {string} - The decrypted password.
 227 |  */
 228 | /**
 229 |  * Decrypt a cryptographic string using the private key.
 230 |  * @param {string} encryptedData - The encrypted string in Base64 format.
 231 |  * @returns {string} - The decrypted password.
 232 |  */
 233 | function decryptPassword(encryptedData) {
 234 |     try {
 235 |         const decryptedPassword = crypto.privateDecrypt(
 236 |             {
 237 |                 key: privateKey,
 238 |                 padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,                                                                                                                                                                 //padding: crypto.constants.RSA_PKCS1_PADDING, // Ensure consistent padding
 239 |             },
 240 |             Buffer.from(encryptedData, 'base64')
 241 |         ).toString('utf8');
 242 | 
 243 |         return decryptedPassword;
 244 |     } catch (error) {
 245 |         logEvent('system', 'conf', l.prefix_PW_Encryption, error.message, 'error'); // Möglicherweise hier ein anderer Prefix benötigt
 246 |         throw new Error(t.decryptPwdError);
 247 |     }
 248 | }
 249 | 
 250 | // Funktion für Verschlüsselung
 251 | function encryptWithPublicKey(data) {
 252 |     try {
 253 |         return crypto.publicEncrypt(
 254 |             {
 255 |                 key: publicKey,
 256 |                 padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, // Explicitly set padding
 257 |             },
 258 |             Buffer.from(data)
 259 |         ).toString('base64');
 260 |     } catch (err) {
 261 |         logEvent('system', 'conf', l.prefix_PW_Encryption, err.message, 'error'); // Möglicherweise hier ein anderer Prefix benötigt
 262 |         throw new Error(t.encryptPwdError);
 263 |     }
 264 | }
 265 | 
 266 | /**
 267 |  * Encrypt a given password and return the encrypted key.
 268 |  * @param {string} password - The password to be encrypted.
 269 |  * @returns {string} - The encrypted password as a Base64 string.
 270 |  */
 271 | function getEncryptedKey(password) {
 272 |     try {
 273 |         return encryptWithPublicKey(password);
 274 |     } catch (err) {
 275 |         // Die Fehlerbehandlung wurde bereits in encryptWithPublicKey durchgeführt
 276 |         throw err;
 277 |     }
 278 | }
 279 | 
 280 | const enableLogin           = getEnvVar('ENABLE_LOGIN', ['Functions', 'ENABLE_LOGIN'], false);
 281 | const enableLogout          = getEnvVar('ENABLE_LOGOUT', ['Functions', 'ENABLE_LOGOUT'], false);
 282 | const enableChat            = getEnvVar('ENABLE_CHAT', ['Functions', 'ENABLE_CHAT'], false);
 283 | const enableContinueChat    = getEnvVar('ENABLE_CONTINUE_CHAT', ['Functions', 'ENABLE_CONTINUE_CHAT'], false);
 284 | const enableGetChatInfo     = getEnvVar('ENABLE_GET_CHAT_INFO', ['Functions', 'ENABLE_GET_CHAT_INFO'], false);
 285 | const enableDeleteAllChats  = getEnvVar('ENABLE_DELETE_ALL_CHATS', ['Functions', 'ENABLE_DELETE_ALL_CHATS'], false);
 286 | const enableDeleteChat      = getEnvVar('ENABLE_DELETE_CHAT', ['Functions', 'ENABLE_DELETE_CHAT'], false);
 287 | const enableListGroups      = getEnvVar('ENABLE_LIST_GROUPS', ['Functions', 'ENABLE_LIST_GROUPS'], false);
 288 | const enableStoreGroup      = getEnvVar('ENABLE_STORE_GROUP', ['Functions', 'ENABLE_STORE_GROUP'], false);
 289 | const enableDeleteGroup     = getEnvVar('ENABLE_DELETE_GROUP', ['Functions', 'ENABLE_DELETE_GROUP'], false);
 290 | const enableCreateSource    = getEnvVar('ENABLE_CREATE_SOURCE', ['Functions', 'ENABLE_CREATE_SOURCE'], false);
 291 | const enableEditSource      = getEnvVar('ENABLE_EDIT_SOURCE', ['Functions', 'ENABLE_EDIT_SOURCE'], false);
 292 | const enableDeleteSource    = getEnvVar('ENABLE_DELETE_SOURCE', ['Functions', 'ENABLE_DELETE_SOURCE'], false);
 293 | const enableGetSource       = getEnvVar('ENABLE_GET_SOURCE', ['Functions', 'ENABLE_GET_SOURCE'], false);
 294 | const enableListSources     = getEnvVar('ENABLE_LIST_SOURCES', ['Functions', 'ENABLE_LIST_SOURCES'], false);
 295 | const enableStoreUser       = getEnvVar('ENABLE_STORE_USER', ['Functions', 'ENABLE_STORE_USER'], false);
 296 | const enableEditUser        = getEnvVar('ENABLE_EDIT_USER', ['Functions', 'ENABLE_EDIT_USER'], false);
 297 | const enableDeleteUser      = getEnvVar('ENABLE_DELETE_USER', ['Functions', 'ENABLE_DELETE_USER'], false);
 298 | const enableReactivateUser  = getEnvVar('ENABLE_REACTIVATE_USER', ['Functions', 'ENABLE_REACTIVATE_USER'], false);
 299 | 
 300 | 
 301 | 
 302 | // Loggen der Server-Konfiguration
 303 | logEvent('system', 'conf', l.prefix_Server_Config, JSON.stringify(envConfig, null, 2), 'info');
 304 | logEvent('system', 'conf', l.prefix_Private_API_URL, privateApiUrl, 'info');
 305 | logEvent('system', 'conf', l.prefix_Public_API_URL, apiUrl, 'info');
 306 | logEvent('system', 'conf', l.prefix_Port, Port, 'info');
 307 | logEvent('system', 'conf', l.prefix_Language, requestedLang, 'info');
 308 | logEvent('system', 'conf', l.prefix_SSL_Validation, sslValidate, 'info');
 309 | logEvent('system', 'conf', l.prefix_EnableTLS, enableTLS, 'info');
 310 | logEvent('system', 'conf', l.prefix_sslKeyPath, sslKeyPath, 'info');
 311 | logEvent('system', 'conf', l.prefix_sslCertPath, sslCertPath, 'info');
 312 | logEvent('system', 'conf', l.prefix_PW_Encryption, PwEncryption ? t.encryptionEnabled : t.encryptionDisabled, 'info');
 313 | logEvent('system', 'conf', l.prefix_Allow_Keygen, AllowKeygen ? t.keygenEnabled : t.keygenDisabled, 'info');
 314 | logEvent('system', 'conf', l.prefix_Private_API_URL, privateKeyPath, 'info'); // Möglicherweise hier ein anderer Prefix benötigt
 315 | logEvent('system', 'conf', l.prefix_Public_API_URL, publicKeyPath, 'info'); // Möglicherweise hier ein anderer Prefix benötigt
 316 | logEvent('system', 'conf', l.prefix_Restricted_Groups, restrictedGroups, 'info');
 317 | logEvent('system', 'conf', l.prefix_openaicompAPI, OpenAICompAPI, 'info');
 318 | logEvent('system', 'conf', l.prefix_WRITTEN_LOGFILE, allowWrittenLogfile, 'info');
 319 | logEvent('system', 'conf', l.prefix_LOG_IPs, LogIps, 'info');
 320 | logEvent('system', 'conf', l.prefix_ANONYMOUS_MODE, anonymousMode, 'info');
 321 | 
 322 | // Loggen der deaktivierten Funktionen
 323 | const allFunctions = [
 324 |   { name: 'Login',              enabled: enableLogin },
 325 |   { name: 'Logout',             enabled: enableLogout },
 326 |   { name: 'Chat',               enabled: enableChat },
 327 |   { name: 'Continue Chat',      enabled: enableContinueChat },
 328 |   { name: 'Get Chat Info',      enabled: enableGetChatInfo },
 329 |   { name: 'Delete All Chats',   enabled: enableDeleteAllChats },
 330 |   { name: 'Delete Chat',        enabled: enableDeleteChat },
 331 |   { name: 'List Groups',        enabled: enableListGroups },
 332 |   { name: 'Store Group',        enabled: enableStoreGroup },
 333 |   { name: 'Delete Group',       enabled: enableDeleteGroup },
 334 |   { name: 'Create Source',      enabled: enableCreateSource },
 335 |   { name: 'Edit Source',        enabled: enableEditSource },
 336 |   { name: 'Delete Source',      enabled: enableDeleteSource },
 337 |   { name: 'Get Source',         enabled: enableGetSource },
 338 |   { name: 'List Sources',       enabled: enableListSources },
 339 |   { name: 'Store User',         enabled: enableStoreUser },
 340 |   { name: 'Edit User',          enabled: enableEditUser },
 341 |   { name: 'Delete User',        enabled: enableDeleteUser },
 342 |   { name: 'Reactivate User',    enabled: enableReactivateUser },
 343 |   // { name: 'Open AI compatible API Chat', enabled: enableChat },
 344 |   // { name: 'Continue Chat', enabled: enableContinueChat },
 345 | ];
 346 | 
 347 | // Filtern, um nur deaktivierte (false) zu bekommen
 348 | const disabledFunctions = allFunctions.filter(f => !f.enabled);
 349 | 
 350 | // Loggen der deaktivierten Funktionen
 351 | if (disabledFunctions.length === 0) {
 352 |     logEvent(
 353 |       'system',
 354 |       'conf',
 355 |       l.prefix_All_Funcs,
 356 |       t.allFunctionsEnabled,
 357 |       'info'
 358 |     );
 359 | } else {
 360 |     logEvent('system', 'conf', l.prefix_Deact_Funcs, t.deactivatedFunctions, 'warn');
 361 |     disabledFunctions.forEach(func => {
 362 |         logEvent('system', 'conf', func.name, t.functionDisabled, 'warn');
 363 |     });
 364 | }
 365 | 
 366 | logEvent('system', 'conf', l.prefix_Validation_Err, t.apiUrlValidated.replace('${url}', apiUrl), 'info');
 367 | 
 368 | // Debugging für RESTRICTED_GROUPS
 369 | logEvent(
 370 |     'system',
 371 |     'conf',
 372 |     l.prefix_Restricted_Groups,
 373 |     t.accessRestrictedGroups.replace('${val}', envConfig.Restrictions?.RESTRICTED_GROUPS.toString()),
 374 |     'info'
 375 | );
 376 | 
 377 | // Zugriff und Validierung von RESTRICTED_GROUPS
 378 | const isRestrictedGroupsEnabled = validateBoolean(
 379 |     'RESTRICTED_GROUPS',
 380 |     restrictedGroups,
 381 |     t
 382 | );
 383 | 
 384 | logEvent('system', 'conf', l.prefix_Restricted_Groups, t.restrictedGroupsSuccess.replace('${status}', isRestrictedGroupsEnabled.toString()), 'info');
 385 | 
 386 | // Zugriff und Validierung von WRITTEN_LOGFILE
 387 | const isWrittenLogfileEnabled = validateBoolean(
 388 |     'WRITTEN_LOGFILE',
 389 |     allowWrittenLogfile,
 390 |     t
 391 | );
 392 | logEvent('system', 'conf', l.prefix_WRITTEN_LOGFILE, t.AllowLoggingSuccess.replace('${status}', isWrittenLogfileEnabled.toString()), 'info');
 393 | setAllowWrittenLogfile(isWrittenLogfileEnabled);
 394 | 
 395 | // Zugriff und Validierung von LOG_IPs
 396 | const isLogIpsEnabled = validateBoolean(
 397 |     'LOG_IPs',
 398 |     LogIps,
 399 |     t
 400 | );
 401 | logEvent('system', 'conf', l.prefix_LOG_IPs, t.LogIpsSuccess.replace('${status}', isLogIpsEnabled.toString()), 'info');
 402 | 
 403 | // Zugriff und Validierung von ANONYMOUS_MODE
 404 | const isanonymousModeEnabled = validateBoolean(
 405 |     'ANONYMOUS_MODE',
 406 |     anonymousMode,
 407 |     t
 408 | );
 409 | logEvent('system', 'conf', l.prefix_ANONYMOUS_MODE, t.anonymousModeSuccess.replace('${status}', isanonymousModeEnabled.toString()), 'info');
 410 | 
 411 | function baseLogOptions() {
 412 |     return {
 413 |         AllowLoggingEnabled: isWrittenLogfileEnabled,
 414 |         LogIps: isLogIpsEnabled,
 415 |         anonymousMode: isanonymousModeEnabled,
 416 |     };
 417 | }
 418 | 
 419 | // SSL-Validierung
 420 | const isSSLValidationEnabled = validateBoolean(
 421 |     'SSL_VALIDATE',
 422 |     getEnvVar('SSL_VALIDATE', ['Server_Config', 'SSL_VALIDATE'], 'false').toString(),
 423 |     t
 424 | );
 425 | 
 426 | const sslSymbol = isSSLValidationEnabled ? '✔️' : '⚠️';
 427 | logEvent('system', 'conf', l.prefix_SSL_Validation,
 428 |     t.sslValidationSet
 429 |         .replace('${symbol}', sslSymbol)
 430 |         .replace('${value}', String(isSSLValidationEnabled)),
 431 |     'info'
 432 | );
 433 | 
 434 | // Port validieren
 435 | const validatedPort = validatePort(Port, t);
 436 | logEvent('system', 'conf', l.prefix_Port_Validated, t.portValidated.replace('${port}', validatedPort), 'info');
 437 | 
 438 | // Einlesen der Proxy_Config-Parameter
 439 | const useProxy = validateBoolean(
 440 |     'USE_PROXY',
 441 |     getEnvVar('USE_PROXY', ['Proxy_Config', 'USE_PROXY'], 'false').toString(),
 442 |     t
 443 | );
 444 | 
 445 | const authHeaderEncrypted = useProxy ? validateBoolean(
 446 |     'HEADER_ENCRYPTED',
 447 |     getEnvVar('HEADER_ENCRYPTED', ['Proxy_Config', 'HEADER_ENCRYPTED'], 'false').toString(),
 448 |     t,
 449 |     useProxy
 450 | ) : false;
 451 | 
 452 | const AccessHeader = useProxy ? getEnvVar('ACCESS_HEADER', ['Proxy_Config', 'ACCESS_HEADER'], null) : null;
 453 | 
 454 | // Verarbeiten des Proxy-Passworts
 455 | let ProxyAccessHeader;
 456 | if (authHeaderEncrypted) {
 457 |     try {
 458 |         ProxyAccessHeader = decryptPassword(AccessHeader);
 459 |     } catch (error) {
 460 |         logEvent('system', 'conf', l.prefix_API_Request_Error, error.message, 'error'); // Möglicherweise hier ein anderer Prefix benötigt
 461 |         process.exit(1);
 462 |     }
 463 | } else {
 464 |     ProxyAccessHeader = AccessHeader;
 465 | }
 466 | 
 467 | // Falls in der HAProxy-Konfiguration ein X-Custom-Header verlangt wird:
 468 | const customHeaderValue = ProxyAccessHeader;
 469 | 
 470 | // Optional: Überprüfen, ob alle erforderlichen Proxy-Daten vorhanden sind
 471 | if (useProxy && authHeaderEncrypted) {
 472 |     if (!ProxyAccessHeader) {
 473 |         logEvent('system', 'conf', l.prefix_API_Request_Error, t.proxyAuthMissing, 'error'); // Möglicherweise hier ein anderer Prefix benötigt
 474 |         process.exit(1);
 475 |     }
 476 | }
 477 | 
 478 | // Ausgabe der Proxy-Konfiguration (mit maskiertem Passwort)
 479 | logEvent('system', 'conf', l.prefix_Proxy_Config, t.proxyUseProxy.replace('${val}', useProxy), 'info');
 480 | 
 481 | // Beispiel: Tool-Überprüfung
 482 | function isToolEnabled(toolName) {
 483 |     const envKey = `ENABLE_${toolName.toUpperCase()}`;
 484 |     if (!(envKey in envConfig.Functions)) {
 485 |         logEvent(
 486 |             'system', 'N/A', l.prefix_Tool_Warn, t.toolNotDefinedInConfig.replace('${toolName}', toolName), 'warn'
 487 |         );
 488 |         return false;
 489 |     }
 490 |     return envConfig.Functions[envKey] === true;
 491 | }
 492 | 
 493 | /* ################ Helper Functions ############################*/
 494 | // Helper-Funktion, um zu prüfen, ob ein Tool aktiviert ist, und eine Fehlermeldung zu generieren
 495 | function checkToolEnabled(toolName) {
 496 |     if (toolName === "keygen" && AllowKeygen) {
 497 |         return null;
 498 |     }
 499 | 
 500 |     if (toolName === "oai_comp_api") {
 501 |         if (OpenAICompAPI) {
 502 |             return null;
 503 |         } else {
 504 |             logEvent('system', 'N/A', l.prefix_Tool_Disabled, t.toolDisabledLog.replace('${toolName}', toolName), 'error');
 505 |         }
 506 |     }
 507 | 
 508 |     if (!OpenAICompAPI || !isToolEnabled(toolName)) {
 509 |         logEvent(
 510 |             'system', 
 511 |             'N/A', 
 512 |             l.prefix_Tool_Disabled, 
 513 |             t.toolDisabledLog.replace('${toolName}', toolName), 
 514 |             'error'
 515 |         );
 516 |         return {
 517 |             status: 'error',
 518 |             message: messages[lang].toolDisabledError.replace('${toolName}', toolName),
 519 |         };
 520 |     }
 521 | 
 522 |     return null; // Tool ist aktiviert
 523 | }
 524 | 
 525 | function validateToken(token) {
 526 |     if (!token) {
 527 |         if (!isanonymousModeEnabled) logEvent('system', 'N/A', l.prefix_API_Request_Error, t.missingTokenError, 'error'); // Möglicherweise hier ein anderer Prefix benötigt
 528 |         return {
 529 |             status: 'error',
 530 |             message: t.missingTokenError,
 531 |             statusCode: 401 // Optional für konsistenten HTTP-Status
 532 |         };
 533 |     }
 534 |     return null;
 535 | }
 536 | 
 537 | function getArguments(input) {
 538 |     if (input.arguments) {
 539 |         return input.arguments;
 540 |     } else if (input.params?.arguments) {
 541 |         return input.params.arguments;
 542 |     } else {
 543 |         if (!isanonymousModeEnabled) logEvent(
 544 |             'system', 'N/A', l.prefix_API_Request_Error, t.invalidArgumentsError.replace('${args}', JSON.stringify(input)), 'error' // Möglicherweise hier ein anderer Prefix benötigt
 545 |         );
 546 |         return {}; // Leeres Objekt als Fallback
 547 |     }
 548 | }
 549 | 
 550 | // Parameter zuordnen
 551 | const API_URL = apiUrl;
 552 | const PORT = Port;
 553 | 
 554 | // Server-Startkonfiguration ausgeben
 555 | const serverConfig = JSON.stringify({ API_URL, PORT }, null, 2); 
 556 | logEvent('system', 'N/A', l.prefix_Server_Config, t.serverStartedLog, 'info');
 557 | // mit Konfiguration: ${serverConfig}
 558 | 
 559 | // Funktion zum Erstellen der Authorization-Header für Basic Auth
 560 | function createBasicAuthHeader(username, password) {
 561 |     const authString = Buffer.from(`${username}:${password}`).toString('base64');
 562 |     return `Basic ${authString}`;
 563 | }
 564 | 
 565 | 
 566 | /* const t = {                             // Beispielhafte Sprachvariablen
 567 |   ConnectionEstablished: 'Verbindung hergestellt',
 568 |   dataReceivedMsg: 'Daten empfangen: ${data}',
 569 |   ResponseSuccessfullySent: 'Antwort erfolgreich gesendet',
 570 |   ConnectionClosed: 'Verbindung geschlossen',
 571 |   ServerStopped: 'Server gestoppt'
 572 | };
 573 | const l = {                             // Beispielhafte Log-Prefixes
 574 |   prefix_tcpServerError: 'TCP-Server Fehler',
 575 |   prefix_Shutdown: 'Herunterfahren'
 576 | };*/
 577 | 
 578 | export class TcpServerTransport {
 579 |     /**
 580 |      * Konstruktor
 581 |      * @param {number} port - Port, auf dem der Server lauschen soll.
 582 |      * @param {boolean} enableTLS - true, wenn SSL/TLS verwendet werden soll, ansonsten false.
 583 |      * @param {string} sslKeyPath - Pfad zur SSL-Schlüsseldatei (nur benötigt, wenn enableTLS true ist).
 584 |      * @param {string} sslCertPath - Pfad zur SSL-Zertifikatsdatei (nur benötigt, wenn enableTLS true ist).
 585 |     */
 586 |     constructor(port, enableTLS, sslKeyPath, sslCertPath) {
 587 |         this.port = port;
 588 |         this.server = null;
 589 |         this.clients = new Map(); // Map zur Speicherung der Clients
 590 |         this.enableTLS = enableTLS; // Flag, ob SSL/TLS verwendet werden soll
 591 |   
 592 |     
 593 |         if (this.enableTLS && (!fs.existsSync(sslKeyPath) || !fs.existsSync(sslCertPath))) {
 594 |             logEvent('system', 'TLS', l.prefix_sslError, t.NoTLSCertFound, 'error');
 595 |             process.exit(1);
 596 |         }
 597 |       // 
 598 |         // Falls SSL aktiviert ist, laden wir die TLS-Optionen (Schlüssel und Zertifikat)
 599 |         if (this.enableTLS) {
 600 |             this.tlsOptions = {
 601 |                 key: fs.readFileSync(sslKeyPath),
 602 |                 cert: fs.readFileSync(sslCertPath)
 603 |                 // Falls CA benötigt wird, z. B.:
 604 |                 // ca: fs.readFileSync(caPath),
 605 |                 // requestCert: false, // oder true, wenn Clients sich per Zertifikat ausweisen sollen
 606 |             };
 607 |         }
 608 |     }
 609 |   
 610 |     /**
 611 |      * Startet den Server.
 612 |      * @param {Function} onMessage - Callback-Funktion, die auf eingehende Nachrichten reagiert.
 613 |      * @returns {Promise} - Wird erfüllt, wenn der Server erfolgreich gestartet wurde.
 614 |      */
 615 |     async start(onMessage) {
 616 |         return new Promise((resolve, reject) => {
 617 |             // Entscheide anhand des enableTLS-Flags, ob ein TLS/SSL-Server oder ein normaler TCP-Server gestartet wird.
 618 |             if (this.enableTLS) {
 619 |                 this.server = tls.createServer(this.tlsOptions, (socket) => {
 620 |                     this.handleConnection(socket, onMessage);
 621 |                 });
 622 |             } else {
 623 |                 this.server = net.createServer((socket) => {
 624 |                     this.handleConnection(socket, onMessage);
 625 |                 });
 626 |             }
 627 |   
 628 |             // Hinzufügen des 'connection'-Listeners (einmalig außerhalb des createServer-Callbacks)
 629 |             this.server.on('connection', (socket) => {
 630 |                 if (!isanonymousModeEnabled) {
 631 |                     logEvent('server', socket.remotePort || 'unknown', 'Connection Established', t.ConnectionEstablished, 'info');
 632 |                 }
 633 |                 socket.setKeepAlive(true, 30000); // Keep-Alive für jede Verbindung
 634 |             });
 635 |       
 636 |             // Server starten
 637 |             this.server.listen(this.port, () => {
 638 |                 const modus = this.enableTLS ? 'TLS/SSL' : 'Plain TCP';
 639 |                 if (!isanonymousModeEnabled) {
 640 |                     logEvent('server', this.port, 'Server Start', `Server lauscht auf Port ${this.port} [${modus}]`, 'info');
 641 |                 }
 642 |                 resolve();
 643 |             });
 644 |       
 645 |             // Fehlerbehandlung auf Server-Ebene
 646 |             this.server.on('error', (err) => {
 647 |                 if (!isanonymousModeEnabled) {
 648 |                     logEvent('server', this.port, l.prefix_tcpServerError, `Serverfehler: ${err.message || err}`, 'error');
 649 |                 }
 650 |                 reject(err);
 651 |             });
 652 |         });
 653 |     }
 654 |   
 655 |     /**
 656 |      * Behandelt eingehende Verbindungen.
 657 |      * @param {object} socket - Das Socket-Objekt der Verbindung.
 658 |      * @param {Function} onMessage - Callback, das auf empfangene Nachrichten reagiert.
 659 |      */
 660 |     handleConnection(socket, onMessage) {
 661 |         const clientIP = socket.remoteAddress || 'unknown';
 662 |         const clientPort = socket.remotePort || 'unknown';
 663 |         this.clients.set(socket, { ip: clientIP, port: clientPort });
 664 |   
 665 |         // Logging: Neue Verbindung
 666 |         if (isLogIpsEnabled) {
 667 |             if (!isanonymousModeEnabled) {
 668 |             logEvent(clientIP, clientPort, 'Connection New', t.ConnectionEstablished, 'info');
 669 |             }
 670 |         } else {
 671 |             if (!isanonymousModeEnabled) {
 672 |                 logEvent('*****', '****', 'Connection New', t.ConnectionEstablished, 'info');
 673 |             }
 674 |         }
 675 |   
 676 |         socket.on('error', (err) => {
 677 |             const client = this.clients.get(socket);
 678 |             // ECONNRESET speziell behandeln
 679 |             if (err.code === 'ECONNRESET') {
 680 |                 // Wenn gewünscht, nur auf „info“-Level loggen oder gar nicht
 681 |                 if (!isanonymousModeEnabled) {
 682 |                     if (isLogIpsEnabled) {
 683 |                         logEvent(
 684 |                         client?.ip || 'unknown',
 685 |                         client?.port || 'unknown',
 686 |                         'Socket Warn',
 687 |                         t.ErrorConnReset,
 688 |                         'info' );
 689 |                     } else {
 690 |                         logEvent(
 691 |                         '*****',
 692 |                         '*****',
 693 |                         'Socket Warn',
 694 |                         t.ErrorConnReset,
 695 |                         'info' );
 696 |                     }
 697 |                 }
 698 |                 return;
 699 |             }
 700 |           
 701 |             // Andere Fehler normal als 'error' loggen
 702 |             if (!isanonymousModeEnabled) {
 703 |                 if (isLogIpsEnabled) {
 704 |                     logEvent(
 705 |                     client?.ip || 'unknown',
 706 |                     client?.port || 'unknown',
 707 |                     'Socket Error',
 708 |                     `Socket-Error: ${err.message || err}`,
 709 |                     'error' );
 710 |                 } else {
 711 |                     logEvent(
 712 |                     '*****',
 713 |                     '*****',
 714 |                     'Socket Error',
 715 |                     `Socket-Error: ${err.message || err}`,
 716 |                     'error' );
 717 |                 };
 718 |             }
 719 |         });
 720 |         // Ereignis: Daten empfangen
 721 |         socket.on('data', async (data) => {
 722 |             const client = this.clients.get(socket);
 723 |             if (isLogIpsEnabled) {
 724 |                 if (!isanonymousModeEnabled) {
 725 |                     logEvent(client.ip, client.port, 'Data Received', t.dataReceivedMsg.replace('${data}', data.toString()), 'info');
 726 |                 }
 727 |             } else {
 728 |                 if (!isanonymousModeEnabled) {
 729 |                     logEvent('*****', '****', 'Data Received', t.dataReceivedMsg.replace('${data}', data.toString()), 'info');
 730 |                     }   
 731 |                 }
 732 |   
 733 |             try {
 734 |                 const message = JSON.parse(data.toString());
 735 |                 const response = await onMessage(message);
 736 |                 const responseString = JSON.stringify(response) + '\n'; // Delimiter hinzufügen
 737 |                 socket.write(responseString, () => {
 738 |                     socket.end(); // Verbindung schließen, wenn das Schreiben fertig ist
 739 |                 });
 740 |       
 741 |                 // Logging: Erfolgreiche Antwort
 742 |                 if (isLogIpsEnabled) {
 743 |                     if (!isanonymousModeEnabled) {
 744 |                         logEvent(client.ip, client.port, 'Response Sent', t.ResponseSuccessfullySent, 'info');
 745 |                     }
 746 |                 } else {
 747 |                     if (!isanonymousModeEnabled) {
 748 |                         logEvent('*****', '****', 'Response Sent', t.ResponseSuccessfullySent, 'info');
 749 |                     }
 750 |                 }
 751 |             } catch (err) {
 752 |                 if (isLogIpsEnabled) {
 753 |                     if (!isanonymousModeEnabled) {
 754 |                         logEvent(client.ip, client.port, 'Error Processing Message', `Fehler: ${err.message || err}`, 'error');
 755 |                     }
 756 |                 } else {
 757 |                     if (!isanonymousModeEnabled) {
 758 |                         logEvent('*****', '****', 'Error Processing Message', `Fehler: ${err.message || err}`, 'error');
 759 |                     }
 760 |                 }
 761 |                 // Sende eine Fehlerantwort mit Delimiter
 762 |                 const errorResponse = JSON.stringify({ error: 'Ungültiges Nachrichtenformat' }) + '\n';
 763 |                 socket.write(errorResponse, () => {
 764 |                     socket.end(); // Verbindung schließen
 765 |                 });
 766 |             }
 767 |         });
 768 |   
 769 |         // Ereignis: Verbindung geschlossen
 770 |         socket.on('close', () => {
 771 |             const client = this.clients.get(socket);
 772 |             if (isLogIpsEnabled) {
 773 |                 if (!isanonymousModeEnabled) {
 774 |                     logEvent(client.ip, client.port, 'Connection Closed', t.ConnectionClosed, 'info');
 775 |                 }
 776 |             } else {
 777 |                 if (!isanonymousModeEnabled) {
 778 |                 logEvent('*****', '****', 'Connection Closed', t.ConnectionClosed, 'info');
 779 |                 }
 780 |             }
 781 |             this.clients.delete(socket); // Entferne den Client aus der Map
 782 |         });
 783 |   
 784 |         // Fehlerbehandlung für einzelne Sockets
 785 |         socket.on('error', (err) => {
 786 |             const client = this.clients.get(socket);
 787 |             if (!isanonymousModeEnabled) {
 788 |                 logEvent(
 789 |                     client?.ip || 'unknown',
 790 |                     client?.port || 'unknown',
 791 |                     'Socket Error',
 792 |                     `Socket-Fehler: ${err.message || err}`,
 793 |                     'error'
 794 |                 );
 795 |             }
 796 |         });
 797 |     }
 798 |   
 799 |     /**
 800 |      * Stoppt den Server und leert die Clientliste.
 801 |      */
 802 |     async stop() {
 803 |         if (this.server) {
 804 |             this.server.close(() => {
 805 |                 if (!isanonymousModeEnabled) {
 806 |                     logEvent('server', this.port, l.prefix_Shutdown, t.ServerStopped, 'info');
 807 |                 }
 808 |             this.clients.clear(); // Alle Clients entfernen
 809 |             });
 810 |         }
 811 |     }
 812 | }
 813 | 
 814 | 
 815 | class PrivateGPTServer {
 816 |     constructor() {
 817 |         this.server = new Server({
 818 |             name: 'pgpt-mcp-server',
 819 |             version: '2.8.0',
 820 |         }, {
 821 |             capabilities: {
 822 |                 resources: {},
 823 |                 tools: {},
 824 |             },
 825 |         });
 826 | 
 827 |         const axiosConfig = {
 828 |           baseURL: apiUrl,
 829 |           headers: {
 830 |             'Accept': 'application/json',
 831 |             'Content-Type': 'application/json',
 832 |           },
 833 |           httpsAgent: new https.Agent({
 834 |             rejectUnauthorized: isSSLValidationEnabled
 835 |           })
 836 |         };
 837 | 
 838 |         // Conditionally Header setzen, wenn USE_PROXY = true
 839 |         if (useProxy) {
 840 |             // Nur wenn der Proxy in der envConfig aktiviert ist,
 841 |             // wird der spezielle Header gesetzt
 842 |             axiosConfig.headers['X-Custom-Header'] = customHeaderValue;
 843 |         } else {
 844 |             // Falls du sicherstellen willst, dass der Header *nicht* gesetzt wird:
 845 |             delete axiosConfig.headers['X-Custom-Header'];
 846 |         }
 847 | 
 848 |         // Axios-Instanz anlegen
 849 |         this.axiosInstance = axios.create(axiosConfig);
 850 |        
 851 |         // Interceptors für Logging von Requests und Responses
 852 |         this.axiosInstance.interceptors.request.use((config) => {
 853 |             const headers = { ...config.headers };
 854 |             if (headers.Authorization) {
 855 |                 // Prüfen, ob es sich um Bearer oder Basic handelt
 856 |                 if (headers.Authorization.startsWith('Bearer ')) {
 857 |                     // Bearer maskieren
 858 |                     headers.Authorization = 'Bearer ********';
 859 |                 } else if (headers.Authorization.startsWith('Basic ')) {
 860 |                     // Basic maskieren
 861 |                     headers.Authorization = 'Basic ********';
 862 |                 } 
 863 |             }
 864 |             if (!isanonymousModeEnabled) logEvent('axios', 'ReqHd', l.prefix_requestHeaders, `Headers: ${JSON.stringify(headers)}`, 'info');
 865 | 
 866 |             return config;
 867 |         }, (error) => {
 868 |             if (!isanonymousModeEnabled) logEvent('axios', 'ReqEr', l.prefix_apiRequestError, t.requestError.replace('${error}', error.message || error), 'error');
 869 |             return Promise.reject(error);
 870 |         });
 871 |         
 872 |         this.axiosInstance.interceptors.response.use((response) => {
 873 |             if (!isanonymousModeEnabled) {
 874 |                 logEvent(
 875 |                     'axios',
 876 |                     'ResOK',
 877 |                     l.prefix_responseReceived,
 878 |                     t.responseReceived.replace('${status}', response?.status?.toString() || 'No Status'),
 879 |                     'info'
 880 |                 );
 881 |             }
 882 |             return response;
 883 |         }, (error) => {
 884 |             const errorMsg = error.response ? JSON.stringify(error.response.data) : error.message;
 885 |             if (!isanonymousModeEnabled) logEvent('axios', 'ResEr', l.prefix_apiRequestError, t.responseError.replace('${error}', errorMsg), 'error');
 886 |             return Promise.reject(error);
 887 |         });
 888 | 
 889 |         this.setupResourceHandlers();
 890 |         this.setupToolHandlers();
 891 | 
 892 |         // Fehlerbehandlung
 893 |         this.server.onerror = (error) => {
 894 |             if (!isanonymousModeEnabled) logEvent(
 895 |                 'server',
 896 |                 'N/A',
 897 |                 l.prefix_MCP_Error,
 898 |                 t.mcpErrorPrefix.replace('${error}', error.message || JSON.stringify(error, null, 2)),
 899 |                 'error'
 900 |             );
 901 |         };
 902 | 
 903 |         process.on('SIGINT', async () => {
 904 |             await this.server.close();
 905 |             if (!isanonymousModeEnabled) logEvent('process', 'N/A', l.prefix_Shutdown, t.serverShutdownLog, 'info');
 906 |             process.exit(0);
 907 |         });
 908 |     }
 909 |     async ensureAuthenticated(token) {
 910 |         if (this.axiosInstance.defaults.headers.common['Authorization']) {
 911 |             delete this.axiosInstance.defaults.headers.common['Authorization'];
 912 |         }
 913 |         this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
 914 |     }
 915 | 
 916 |     /**
 917 |      * Login-Funktion mit Logging
 918 |      * @param {string} email - Benutzer-E-Mail
 919 |      * @param {string} password - Benutzer-Passwort
 920 |      * @returns {string} - Authentifizierungs-Token
 921 |      */
 922 |     async login(email, password) {
 923 |         if (!isanonymousModeEnabled) logEvent(email, 'N/A', l.prefix_login, t.authStarted, 'info');
 924 |         try {
 925 |             const loginResponse = await this.axiosInstance.post('/login', {
 926 |                 email,
 927 |                 password
 928 |             });
 929 |             if (!isanonymousModeEnabled) logEvent(
 930 |                 email,
 931 |                 'N/A',
 932 |                 l.prefix_loginSuccess,
 933 |                 t.loginTokenReceived.replace('${token}', loginResponse.data.data.token),
 934 |                 'info'
 935 |             );
 936 |             return loginResponse.data.data.token;
 937 |         } catch (error) {
 938 |             if (!isanonymousModeEnabled) logEvent(
 939 |                 email,
 940 |                 'N/A',
 941 |                 l.prefix_loginError,
 942 |                 t.loginErrorPrefix.replace('${error}', error.message || error),
 943 |                 'error'
 944 |             );
 945 |             throw new Error(t.authFailed);
 946 |         }
 947 |     }
 948 | 
 949 | 
 950 |     /**
 951 |      * Authentifizierung sicherstellen mit Logging
 952 |      * @param {string} token - Authentifizierungs-Token
 953 |      */
 954 |     async ensureAuthenticated(token) {
 955 |         if (!token) {
 956 |             if (!isanonymousModeEnabled) logEvent('auth', 'check', l.prefix_apiRequestError, t.missingTokenError, 'error');
 957 |             throw new Error(t.missingTokenError);
 958 |         }
 959 | 
 960 |         if (!isanonymousModeEnabled) logEvent('auth', 'token', l.prefix_apiRequestError, t.settingToken, 'info');
 961 | 
 962 |         // Entferne den Basic Auth Header, falls vorhanden
 963 |         if (this.axiosInstance.defaults.headers.common['Authorization']) {
 964 |             delete this.axiosInstance.defaults.headers.common['Authorization'];
 965 |         }
 966 | 
 967 |         // Setze das Token als Authorization-Header
 968 |         this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
 969 |         if (!isanonymousModeEnabled) logEvent('axios', 'Auth', l.prefix_loginSuccess, t.tokenSetSuccess, 'info');
 970 |     }
 971 | 
 972 | 
 973 |     /**
 974 |      * Gruppen validieren mit Logging
 975 |      * @param {Array} groups - Gruppenliste
 976 |      * @param {string} token - Authentifizierungs-Token
 977 |      * @returns {Object} - Validierungsergebnis
 978 |      */
 979 |     async validateGroups(groups, token, IP, Port) {
 980 |         try {
 981 |             if (!isanonymousModeEnabled) logEvent(
 982 |                 IP,
 983 |                 Port,
 984 |                 l.prefix_Incoming_Message,
 985 |                 t.checkingGroups.replace('${groups}', JSON.stringify(groups)),
 986 |                 'info'
 987 |             );
 988 |             if (!token) {
 989 |                 if (!isanonymousModeEnabled) logEvent(IP, Port, l.prefix_apiRequestError, t.missingTokenError, 'error');
 990 |                 throw new Error(t.missingTokenGroups);
 991 |             }
 992 | 
 993 |             const response = await this.axiosInstance.get('/groups', {
 994 |                 headers: { Authorization: `Bearer ${token}` }
 995 |             });
 996 | 
 997 |             const availableGroups = response.data?.data?.assignableGroups || [];
 998 |             if (!isanonymousModeEnabled) logEvent(IP, Port, 'Available Groups', t.availableGroups.replace('${availableGroups}', JSON.stringify(availableGroups)), 'info');
 999 |             const invalidGroups = groups.filter(group => !availableGroups.includes(group));
1000 |             if (invalidGroups.length > 0) {
1001 |                 if (!isanonymousModeEnabled) logEvent(
1002 |                     'validateGroups',
1003 |                     'N/A',
1004 |                     l.prefix_validationErr,
1005 |                     t.invalidGroupsLog.replace('${groups}', JSON.stringify(invalidGroups)),
1006 |                     'error'
1007 |                 );
1008 |                 return { isValid: false, invalidGroups };
1009 |             }
1010 |             if (!isanonymousModeEnabled) logEvent(IP, Port, 'Validation OK', t.allGroupsValid, 'info');
1011 |             return { isValid: true };
1012 |         } catch (error) {
1013 |             const errorMessage = error.response?.data || error.message;
1014 |             if (!isanonymousModeEnabled) logEvent(
1015 |                 'validateGroups',
1016 |                 'N/A',
1017 |                 l.prefix_Validation_Err,
1018 |                 t.groupValidationErrorPrefix.replace('${error}', errorMessage),
1019 |                 'error'
1020 |             );
1021 |             throw new Error(
1022 |                 error.response?.data?.message || t.fetchGroupsErrorBackup
1023 |             );
1024 |         }
1025 |     }
1026 |     setupResourceHandlers() {
1027 |         // List available resources
1028 |         this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
1029 |             resources: []
1030 |         }));
1031 |         // List resource templates
1032 |         this.server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
1033 |             resourceTemplates: []
1034 |         }));
1035 |         // Read resource
1036 |         this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
1037 |             if (!request.params?.uri) {
1038 |                 throw new McpError(
1039 |                     ErrorCode.InvalidRequest,
1040 |                     t.missingUriParameter
1041 |                 );
1042 |             }
1043 |             throw new McpError(ErrorCode.InvalidRequest, `Invalid URI: ${request.params.uri}`);
1044 |         });
1045 |     }
1046 | 
1047 |     setupToolHandlers() {
1048 |         this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
1049 |             tools: [
1050 |             {   /* 1.0 Login #####################################################################################*/
1051 |                 name: 'login',
1052 |                 description: 'User login to retrieve an API token',
1053 |                 inputSchema: {
1054 |                     type: 'object',
1055 |                     properties: {
1056 |                         email: {
1057 |                             type: 'string',
1058 |                             description: 'User email address for login'
1059 |                         },
1060 |                         password: {
1061 |                             type: 'string',
1062 |                             description: 'User password for login'
1063 |                         }
1064 |                     },
1065 |                     required: ['email', 'password']
1066 |                 }
1067 |             },
1068 |             {   /* 1.1 Logout ####################################################################################*/
1069 |                 name: 'logout',
1070 |                 description: 'Invalidate the API token',
1071 |                 inputSchema: { type: 'object', properties: {} },
1072 |             },
1073 |             {   /* 2.0 Chat ######################################################################################*/
1074 |                 name: 'chat',
1075 |                 description: 'Start or continue a chat with PrivateGPT with optional RAG capabilities',
1076 |                 inputSchema: {
1077 |                     type: 'object',
1078 |                     properties: {
1079 |                         question: { type: 'string', description: 'The question or prompt to send' },
1080 |                         usePublic: { type: 'boolean', description: 'Use public knowledge base', default: false },
1081 |                         groups: {
1082 |                             type: 'array',
1083 |                             items: { type: 'string' },
1084 |                             description: 'Group names for RAG (exclusive with usePublic)',
1085 |                         },
1086 |                         language: { type: 'string', description: 'Language code (e.g., "en")', default: 'en' },
1087 |                     },
1088 |                     required: ['question'],
1089 |                 },
1090 |             },
1091 |             {   /* 2.1 Continue Chat #############################################################################*/
1092 |                 name: 'continue_chat',
1093 |                 description: 'Continue an existing chat',
1094 |                 inputSchema: {
1095 |                     type: 'object',
1096 |                     properties: {
1097 |                         chatId: { type: 'string', description: 'ID of the existing chat to continue' },
1098 |                         question: { type: 'string', description: 'The next question or message in the chat' },
1099 |                     },
1100 |                     required: ['chatId', 'question'],
1101 |                 },
1102 |             },
1103 |             {   /* 2.2 Get Chat Info #############################################################################*/
1104 |                 name: 'get_chat_info',
1105 |                 description: 'Retrieve details about an existing chat using its ID',
1106 |                 inputSchema: {
1107 |                     type: 'object',
1108 |                     properties: {
1109 |                         chatId: { type: 'string', description: 'ID of the chat to retrieve details for' },
1110 |                         token: { type: 'string', description: 'Authorization token for API access' },
1111 |                     },
1112 |                     required: ['chatId', 'token'],
1113 |                 },
1114 |             },
1115 |             {   /* 3.0 Create Source #############################################################################*/
1116 |                 name: 'create_source',
1117 |                 description: 'Create a new source with automatic markdown formatting',
1118 |                 inputSchema: {
1119 |                     type: 'object',
1120 |                     properties: {
1121 |                         name: { type: 'string', description: 'Name of the source' },
1122 |                         content: { type: 'string', description: 'Markdown-formatted content' },
1123 |                         groups: {
1124 |                             type: 'array',
1125 |                             items: { type: 'string' },
1126 |                             description: 'Optional groups to assign the source to',
1127 |                         },
1128 |                     },
1129 |                     required: ['name', 'content'],
1130 |                 },
1131 |             },
1132 |             {   /* 3.1 Get Source ################################################################################*/
1133 |                 name: 'get_source',
1134 |                 description: 'Retrieve information about a specific source',
1135 |                 inputSchema: {
1136 |                     type: 'object',
1137 |                     properties: {
1138 |                         sourceId: { type: 'string', description: 'ID of the source to retrieve' },
1139 |                     },
1140 |                     required: ['sourceId'],
1141 |                 },
1142 |             },
1143 |             {   /* 3.2 List Sources ##############################################################################*/
1144 |                 name: 'list_sources',
1145 |                 description: 'List all sources in a specific group',
1146 |                 inputSchema: {
1147 |                     type: 'object',
1148 |                     properties: {
1149 |                         groupName: { type: 'string', description: 'Group name to list sources from' },
1150 |                     },
1151 |                     required: ['groupName'],
1152 |                 },
1153 |             },
1154 |             {   /* 3.3 Edit Source ###############################################################################*/
1155 |                 name: 'edit_source',
1156 |                 description: 'Edit an existing source',
1157 |                 inputSchema: {
1158 |                     type: 'object',
1159 |                     properties: {
1160 |                         sourceId: {
1161 |                             type: 'string',
1162 |                             description: 'ID of the source to edit'
1163 |                         },
1164 |                         token: {
1165 |                             type: 'string',
1166 |                             description: 'Authorization token for API access'
1167 |                         },
1168 |                         title: {
1169 |                             type: 'string',
1170 |                             description: 'New title for the source (optional)'
1171 |                         },
1172 |                         content: {
1173 |                             type: 'string',
1174 |                             description: 'New markdown-formatted content for the source (optional)'
1175 |                         },
1176 |                         groups: {
1177 |                             type: 'array',
1178 |                             items: {
1179 |                                 type: 'string'
1180 |                             },
1181 |                             description: 'Updated group(s) to assign to the source (optional)'
1182 |                         }
1183 |                     },
1184 |                     required: ['sourceId', 'token']
1185 |                 }
1186 |             },
1187 |             {   /* 3.4 Delete Source #############################################################################*/
1188 |                 name: 'delete_source',
1189 |                 description: 'Delete a specific source',
1190 |                 inputSchema: {
1191 |                     type: 'object',
1192 |                     properties: {
1193 |                         sourceId: { type: 'string', description: 'ID of the source to delete' },
1194 |                     },
1195 |                     required: ['sourceId'],
1196 |                 },
1197 |             },
1198 |             {   /* 4.0 List Groups ###############################################################################*/
1199 |                 name: 'list_groups',
1200 |                 description: 'Retrieve personal and assignable groups',
1201 |                 inputSchema: { type: 'object', properties: {} },
1202 |             },
1203 |             {   /* 4.1 Store Group ###############################################################################*/
1204 |                 name: 'store_group',
1205 |                 description: 'Create a new group',
1206 |                 inputSchema: {
1207 |                     type: 'object',
1208 |                     properties: {
1209 |                         groupName: { type: 'string', description: 'Name of the new group' },
1210 |                         description: { type: 'string', description: 'Description of the new group' },
1211 |                     },
1212 |                     required: ['groupName'],
1213 |                 },
1214 |             },
1215 |             {   /* 4.2 Delete Group ##############################################################################*/
1216 |                 name: 'delete_group',
1217 |                 description: 'Delete an existing group',
1218 |                 inputSchema: {
1219 |                     type: 'object',
1220 |                     properties: {
1221 |                         groupName: { type: 'string', description: 'Name of the group to delete' },
1222 |                     },
1223 |                     required: ['groupName'],
1224 |                 },
1225 |             },
1226 |             {   /* 5.0 Store User ################################################################################*/
1227 |                 name: 'store_user',
1228 |                 description: 'Create a new user',
1229 |                 inputSchema: {
1230 |                     type: 'object',
1231 |                     properties: {
1232 |                         name: { type: 'string', description: 'Name of the user' },
1233 |                         email: { type: 'string', description: 'Email of the user' },
1234 |                         password: { type: 'string', description: 'Password for the user' },
1235 |                         language: { type: 'string', description: 'Preferred language (optional)', default: 'en' },
1236 |                         timezone: { type: 'string', description: 'Timezone (optional)', default: 'Europe/Berlin' },
1237 |                         roles: {
1238 |                             type: 'array',
1239 |                             items: { type: 'string' },
1240 |                             description: 'Roles to assign (optional)'
1241 |                         },
1242 |                         groups: {
1243 |                             type: 'array',
1244 |                             items: { type: 'string' },
1245 |                             description: 'Groups to assign (optional)'
1246 |                         },
1247 |                         usePublic: { type: 'boolean', description: 'Enable public knowledge (optional)', default: false }
1248 |                     },
1249 |                     required: ['name', 'email', 'password']
1250 |                 },
1251 |             },
1252 |             {   /* 5.1 Edit User #################################################################################*/
1253 |                 name: 'edit_user',
1254 |                 description: 'Edit an existing user',
1255 |                 inputSchema: {
1256 |                     type: 'object',
1257 |                     properties: {
1258 |                         email: { type: 'string', description: 'Email of the user to edit' },
1259 |                         name: { type: 'string', description: 'New name for the user (optional)' },
1260 |                         password: { type: 'string', description: 'New password for the user (optional)' },
1261 |                         language: { type: 'string', description: 'Preferred language (optional)' },
1262 |                         timezone: { type: 'string', description: 'Timezone (optional)' },
1263 |                         roles: {
1264 |                             type: 'array',
1265 |                             items: { type: 'string' },
1266 |                             description: 'Updated roles (optional)'
1267 |                         },
1268 |                         groups: {
1269 |                             type: 'array',
1270 |                             items: { type: 'string' },
1271 |                             description: 'Updated groups (optional)'
1272 |                         },
1273 |                         usePublic: { type: 'boolean', description: 'Enable public knowledge (optional)' }
1274 |                     },
1275 |                     required: ['email']
1276 |                 }
1277 |             },
1278 |             {   /* 5.2 Delete User ###############################################################################*/
1279 |                 name: 'delete_user',
1280 |                 description: 'Delete an existing user',
1281 |                 inputSchema: {
1282 |                     type: 'object',
1283 |                     properties: {
1284 |                         email: { type: 'string', description: 'Email of the user to delete' }
1285 |                     },
1286 |                     required: ['email']
1287 |                 }
1288 |             },
1289 | 			{   /* 6.0 pen AI compatible API Chat ######################################################################################*/
1290 |                 name: 'oai_comp_api_chat',
1291 |                 description: 'Start or continue a chat with PrivateGPT with optional RAG capabilities',
1292 |                 inputSchema: {
1293 |                     type: 'object',
1294 |                     properties: {
1295 |                         question: { type: 'string', description: 'The question or prompt to send' },
1296 |                         usePublic: { type: 'boolean', description: 'Use public knowledge base', default: false },
1297 |                         groups: {
1298 |                             type: 'array',
1299 |                             items: { type: 'string' },
1300 |                             description: 'Group names for RAG (exclusive with usePublic)',
1301 |                         },
1302 |                         language: { type: 'string', description: 'Language code (e.g., "en")', default: 'en' },
1303 |                     },
1304 |                     required: ['question'],
1305 |                 },
1306 |             },
1307 |             {   /* 6.1 Open AI compatible API Continue Chat #############################################################################*/
1308 |                 name: 'oai_comp_api_continue_chat',
1309 |                 description: 'Continue an existing chat',
1310 |                 inputSchema: {
1311 |                     type: 'object',
1312 |                     properties: {
1313 |                         chatId: { type: 'string', description: 'ID of the existing chat to continue' },
1314 |                         question: { type: 'string', description: 'The next question or message in the chat' },
1315 |                     },
1316 |                     required: ['chatId', 'question'],
1317 |                 },
1318 |             }
1319 |         ],
1320 |     }));
1321 | 
1322 |         this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
1323 |             if (!request.params?.name) {
1324 |                 throw new McpError(
1325 |                     ErrorCode.InvalidRequest,
1326 |                     t.missingToolName
1327 |                 );
1328 |             }
1329 |             try {
1330 |                 //await this.ensureAuthenticated();
1331 |                 if (!isanonymousModeEnabled) logEvent(
1332 |                     'system',
1333 |                     'N/A',
1334 |                     l.prefix_Handling_Tool_Request,
1335 |                     t.handlingToolRequest.replace('${tool}', request.params.name),
1336 |                     'info'
1337 |                 );
1338 |                 switch (request.params.name) {
1339 |                     /* 1.0 Login ######################################################################################*/
1340 |                     case 'login': {
1341 |                         const disabledResponse = checkToolEnabled('login');
1342 |                         if (disabledResponse) return disabledResponse;
1343 | 
1344 |                         const { email, password } = request.params.arguments; // Extrahiere email und password aus der Nachricht
1345 | 
1346 |                         if (!email || !password) {
1347 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_loginError, t.loginMissingCredentialsAlternative, 'error');
1348 |                             return {
1349 |                                 status: 'E10-R-1000',
1350 |                                 message: t.loginEmailPasswordRequired
1351 |                             };
1352 |                         }
1353 | 
1354 |                         try {
1355 |                             // Aufruf des Login-Endpunkts der API
1356 |                             const loginResponse = await this.axiosInstance.post('/login', { email, password });
1357 | 
1358 |                             // Loggen des erfolgreichen Logins
1359 |                             if (!isanonymousModeEnabled) logEvent(
1360 |                                 'server',
1361 |                                 'swreg',
1362 |                                 l.prefix_loginSuccess,
1363 |                                 t.loginTokenReceived.replace('${token}', JSON.stringify(loginResponse.data)),
1364 |                                 'info'
1365 |                             );
1366 |                             return { // Token zurückgeben
1367 |                                 status: loginResponse.data?.status || 'I10-R-1001', // Dynamisch, falls der API-Status einheitlich ist
1368 |                                 message: loginResponse.data?.message || '1.0 Login', // API-Nachricht verwenden oder Standardnachricht
1369 |                                 token: loginResponse.data?.data?.token // Token aus API-Antwort
1370 |                             };
1371 |                         } catch (error) {
1372 |                             const errorMessage = error.response?.data?.message || error.message || t.unknownError;
1373 | 
1374 |                             // Loggen des Fehlers beim Login
1375 |                             if (!isanonymousModeEnabled) logEvent(
1376 |                                 'server',
1377 |                                 'swreg',
1378 |                                 l.prefix_loginError,
1379 |                                 t.loginError.replace('${error}', errorMessage),
1380 |                                 'error'
1381 |                             );
1382 | 
1383 |                             return {
1384 |                                 status: error.response?.status || 'E10-R-1001', // API-Fehlerstatus oder Standardfehlerstatus
1385 |                                 message: errorMessage,
1386 |                             };
1387 |                         }
1388 |                     }
1389 |                    /* 1.1 Logout #####################################################################################*/
1390 |                     case 'logout': {
1391 |                         const disabledResponse = checkToolEnabled('logout');
1392 |                         if (disabledResponse) return disabledResponse;
1393 | 
1394 |                         const { token } = request.params; // Korrigiert von 'message' zu 'request.params'
1395 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_logout, t.extractedToken.replace('${token}', token), 'info');
1396 | 
1397 |                         const tokenValidation = validateToken(token);
1398 |                         if (tokenValidation) return tokenValidation;
1399 | 
1400 |                         try {
1401 |                             // Setze den Bearer Token als Standard-Authorization-Header
1402 |                             await this.ensureAuthenticated(token);
1403 | 
1404 |                             // Console-Log für Header zu Debug-Zwecken
1405 |                             console.log('Logout Request Headers:', this.axiosInstance.defaults.headers.common);
1406 |                             const logoutResponse = await this.axiosInstance.delete('/logout', { headers: { Authorization: `Bearer ${token}` }})
1407 | 
1408 |                             // Loggen des erfolgreichen Logouts
1409 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_logoutSuccess, t.logoutSuccess.replace('${data}', JSON.stringify(logoutResponse.data)), 'info');
1410 | 
1411 |                             return {
1412 |                                 data: {}, // Optional: Zusätzliche Daten könnten hier eingefügt werden
1413 |                                 message: 'success',
1414 |                                 status: 200, // OK
1415 |                             };
1416 |                         } catch (error) {
1417 |                             const logoutErrorMessage = error.response?.data || error.message;
1418 |                             // Loggen des Fehlers beim Logout
1419 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_logoutError, t.logoutError.replace('${error}', logoutErrorMessage), 'error');
1420 | 
1421 |                             return {
1422 |                                 data: {},
1423 |                                 message: error.response?.data?.message || t.logoutFailedTryAgain,
1424 |                                 status: error.response?.status || 'E11-R-1100', // Internal Server Error oder spezifischer Statuscode
1425 |                             };
1426 |                         }
1427 |                     }
1428 |                     /* 2.0 Chat #######################################################################################*/
1429 |                     case 'chat': {
1430 |                         const disabledResponse = checkToolEnabled('chat');
1431 |                         if (disabledResponse) return disabledResponse;
1432 | 
1433 |                         const { token, arguments: args } = request.params;
1434 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chat, t.extractedToken.replace('${token}', token), 'info');
1435 | 
1436 |                         // Token prüfen und validieren
1437 |                         if (!token) {
1438 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatError, t.noTokenError, 'error');
1439 |                             return { status: 'E20-R-2000', message: t.missingTokenError };
1440 |                         }
1441 |                         
1442 |                         const tokenValidation = validateToken(token);
1443 |                         if (tokenValidation) return tokenValidation;
1444 |                         
1445 |                         // Argument-Validierung
1446 |                         if (!args || !args.question) {
1447 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatError, t.missingArgumentsError.replace('${args}', JSON.stringify(args)), 'error');
1448 |                             return {
1449 |                                 status: 'error',
1450 |                                 message: t.missingArgumentsError.replace('${args}', JSON.stringify(args)),
1451 |                             };
1452 |                         }
1453 | 
1454 |                         const { question, usePublic, groups, language } = args;
1455 | 
1456 |                         // Konflikt zwischen `usePublic` und `groups` lösen
1457 |                         if (usePublic && groups && groups.length > 0) {
1458 |                             if (!isanonymousModeEnabled) logEvent('system', 'swreg', l.prefix_chatWarning, t.publicGroupsConflictWarning, 'warn');
1459 |                             args.usePublic = false;
1460 |                         }
1461 | 
1462 |                         try {
1463 |                             // Loggen der Chat-Anfrage
1464 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatRequest, t.sendingChatRequest
1465 |                                 .replace('${question}', question)
1466 |                                 .replace('${usePublic}', usePublic)
1467 |                                 .replace('${groups}', JSON.stringify(groups))
1468 |                                 .replace('${language}', language), 'info');
1469 | 
1470 |                             const response = await this.axiosInstance.post(
1471 |                                 '/chats',
1472 |                                 {
1473 |                                     question,
1474 |                                     usePublic: usePublic || false,
1475 |                                     groups: Array.isArray(groups) ? groups : [groups],
1476 |                                     language: language || 'de',
1477 |                                 },
1478 |                                 { headers: { Authorization: `Bearer ${token}` } }
1479 |                             );
1480 | 
1481 |                             const data = response.data?.data || {};
1482 |                             // Loggen der erfolgreichen Chat-Antwort
1483 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatSuccess, t.chatResponseSuccess.replace('${data}', JSON.stringify(data)), 'info');
1484 | 
1485 |                             // Erfolgsantwort mit Status und Daten
1486 |                             return {
1487 |                                 status: response.data?.status || 'ok',
1488 |                                 message: response.data?.message || 'Chat erfolgreich.',
1489 |                                 content: {
1490 |                                     chatId: data.chatId,
1491 |                                     answer: data.answer,
1492 |                                     sources: data.sources || [],
1493 |                                 },
1494 |                             };
1495 |                         } catch (error) {
1496 |                             const chatApiErrorMessage = error.message || error.response?.data;
1497 |                             // Loggen des Fehlers bei der Chat-API-Anfrage
1498 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatApiError, t.chatApiError.replace('${error}', chatApiErrorMessage), 'error');
1499 | 
1500 |                             // Fehlerantwort mit Status und Nachricht
1501 |                             return {
1502 |                                 status: error.response?.status || 'E20-R-2002',
1503 |                                 message: error.response?.data?.message || t.chatApiErrorDefault,
1504 |                             };
1505 |                         }
1506 |                     }
1507 |                     /* 2.1 Continue Chat ##############################################################################*/
1508 |                     case 'continue_chat': {
1509 |                         const disabledResponse = checkToolEnabled('continue_chat');
1510 |                         if (disabledResponse) return disabledResponse;
1511 | 
1512 |                         const args = request.params.arguments;
1513 | 
1514 |                         if (!args || !args.chatId || !args.question) {
1515 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chatError, t.missingChatParams, 'error');
1516 |                             return {
1517 |                               status: 'E21-R-2100',
1518 |                               message: t.missingChatParams
1519 |                             };
1520 |                         }
1521 | 
1522 |                         const { chatId, question } = args;
1523 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chat, t.conversationContinuation.replace('${chatId}', chatId), 'info');
1524 | 
1525 |                         try {
1526 |                             const continueChatResponse = await this.axiosInstance.patch(`/chats/${chatId}`, {
1527 |                                 question: question,
1528 |                             });
1529 |                             // Loggen der erfolgreichen Fortsetzung der Konversation
1530 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chatSuccess, t.conversationSuccess.replace('${data}', JSON.stringify(continueChatResponse.data, null, 2)), 'info');
1531 |                             return {
1532 |                                 content: {
1533 |                                     chatId:  continueChatResponse.data.data.chatId,
1534 |                                     answer:  continueChatResponse.data.data.answer,
1535 |                                     sources: continueChatResponse.data.sources || [],
1536 |                                     message: continueChatResponse.data.message,
1537 |                                     status:  continueChatResponse.data.status,
1538 |                                 },
1539 |                             };
1540 |                         } catch (error) {
1541 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chatError, t.apiRequestError.replace('${error}', error.message), 'error');
1542 |                             return {
1543 |                               status: error.response?.status || 'E21-R-2101',
1544 |                               message: error.response?.data?.message || t.continueConversationError,
1545 |                             };
1546 |                         }
1547 |                     }
1548 |                     /* 2.2 Get Chat Info ##############################################################################*/
1549 |                     case 'get_chat_info': {
1550 |                         const disabledResponse = checkToolEnabled('get_chat_info');
1551 |                         if (disabledResponse) return disabledResponse;
1552 | 
1553 |                         const { token, arguments: args } = request.params;
1554 | 
1555 |                         const tokenValidation = validateToken(token);
1556 |                         if (tokenValidation) return tokenValidation;
1557 | 
1558 |                         const { chatId } = args;
1559 | 
1560 |                         if (!chatId) {
1561 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_chat_infoError, t.missingChatId, 'error');
1562 |                             return { status: 'E22-R-2200', message: t.missingChatId };
1563 |                         }
1564 | 
1565 |                         try {
1566 |                             const response = await this.axiosInstance.get(`/chats/${chatId}`, {
1567 |                                 headers: { Authorization: `Bearer ${token}` }
1568 |                             });
1569 | 
1570 |                             const chatData = response.data?.data;
1571 | 
1572 |                             if (!chatData) {
1573 |                                 if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_chat_infoError, t.noChatData, 'error');
1574 |                                 return {
1575 |                                     status: 'E22-R-2201',
1576 |                                     message: t.noChatData,
1577 |                                 };
1578 |                             }
1579 | 
1580 |                             // Loggen der abgerufenen Chat-Informationen
1581 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_chat_infoSuccess, t.chatInfoRetrieved.replace('${chatData}', JSON.stringify(chatData)), 'info');
1582 | 
1583 |                             return {
1584 |                                 data: {
1585 |                                     chatId: chatData.chatId,
1586 |                                     title: chatData.title || 'Unbenannter Chat',
1587 |                                     language: chatData.language || 'Unbekannt',
1588 |                                     groups: chatData.groups || [],
1589 |                                     messages: chatData.messages || []
1590 |                                 },
1591 |                                 message: response.data?.message || 'Erfolgreich abgerufen.'
1592 |                             };
1593 |                         } catch (error) {
1594 |                             const fetchChatErrorMessage = error.message || error.response?.data;
1595 |                             // Loggen des Fehlers beim Abrufen der Chat-Informationen
1596 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_chat_infoError, t.fetchChatInfoError.replace('${error}', fetchChatErrorMessage), 'error');
1597 |                             return {
1598 |                                 status: 'E22-R-2202',
1599 |                                 message: error.response?.data?.message || 'Fehler beim Abrufen der Chat-Informationen.'
1600 |                             };
1601 |                         }
1602 |                     }                  
1603 |                     /* 2.3 Delete All Chats ##############################################################################*/
1604 |                     case 'delete_all_chats': {
1605 |                         const disabledResponse = checkToolEnabled('delete_all_chats');
1606 |                         if (disabledResponse) return disabledResponse;
1607 | 
1608 |                         const { token } = request.params;
1609 | 
1610 |                         const tokenValidation = validateToken(token);
1611 |                         if (tokenValidation) return tokenValidation;
1612 | 
1613 |                         try {
1614 |                             const response = await this.axiosInstance.delete('/chats/flush', {
1615 |                                 headers: { 
1616 |                                     Authorization: `Bearer ${token}`,
1617 |                                     Accept: 'application/json'
1618 |                                 }
1619 |                             });
1620 | 
1621 |                             // Erfolg loggen
1622 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_all_chatsSuccess, t.chatsDeleted, 'info');
1623 | 
1624 |                             return {
1625 |                                 data: {},
1626 |                                 message: response.data?.message || 'success',
1627 |                                 status: response.status || 200
1628 |                             };
1629 |                         } catch (error) {
1630 |                             const deleteChatsErrorMessage = error.message || error.response?.data;
1631 |                             
1632 |                             // Fehler loggen
1633 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_all_chatsError, t.deleteChatsError.replace('${error}', deleteChatsErrorMessage), 'error');
1634 | 
1635 |                             return {
1636 |                                 status: error.response?.status || 'E23-R-2300',
1637 |                                 message: error.response?.data?.message || 'Error deleting all chat history.'
1638 |                             };
1639 |                         }
1640 |                     }
1641 |                     /* 2.4 Delete Specific Chat ##############################################################################*/
1642 |                     case 'delete_chat': {
1643 |                         const disabledResponse = checkToolEnabled('delete_chat');
1644 |                         if (disabledResponse) return disabledResponse;
1645 | 
1646 |                         const { token, arguments: args } = request.params;
1647 | 
1648 |                         const tokenValidation = validateToken(token);
1649 |                         if (tokenValidation) return tokenValidation;
1650 | 
1651 |                         const { chatId } = args;
1652 | 
1653 |                         if (!chatId) {
1654 |                             return { status: 'E24-R-2400', message: t.missingChatId };
1655 |                         }
1656 | 
1657 |                         try {
1658 |                             const response = await this.axiosInstance.delete(`/chats/${chatId}`, {
1659 |                                 headers: { 
1660 |                                     Authorization: `Bearer ${token}`,
1661 |                                     Accept: 'application/json'
1662 |                                 }
1663 |                             });
1664 | 
1665 |                             // Erfolg loggen
1666 |                             if (!isanonymousModeEnabled) {
1667 |                                 logEvent('server', 'swreg', l.prefix_delete_chatSuccess, t.chatDeleted.replace('${chatId}', chatId), 'info');
1668 |                             }
1669 | 
1670 |                             return {
1671 |                                 data: {},
1672 |                                 message: response.data?.message || 'success',
1673 |                                 status: response.status || 200
1674 |                             };
1675 |                         } catch (error) {
1676 |                             const deleteChatErrorMessage = error.message || error.response?.data;
1677 |                             
1678 |                             // Fehler loggen
1679 |                             if (!isanonymousModeEnabled) {
1680 |                                 logEvent('server', 'swreg', l.prefix_delete_chatError, 
1681 |                                          t.deleteChatError.replace('${chatId}', chatId).replace('${error}', deleteChatErrorMessage), 'error');
1682 |                             }
1683 | 
1684 |                             return {
1685 |                                 status: error.response?.status || 'E24-R-2401',
1686 |                                 message: error.response?.data?.message || `Error deleting chat with ID ${chatId}.`
1687 |                             };
1688 |                         }
1689 |                     }
1690 |                     /* 3.0 Create Source ##############################################################################*/
1691 |                     case 'create_source': {
1692 |                         const disabledResponse = checkToolEnabled('create_source');
1693 |                         if (disabledResponse) return disabledResponse;
1694 | 
1695 |                         const args = request.params.arguments;
1696 |                         const token = request.params.token;
1697 | 
1698 |                         // Validierung: Erforderliche Parameter prüfen
1699 |                         if (!token) {
1700 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceError, t.tokenMissing, 'error');
1701 |                             return { status: 'E30-R-3000', message: t.missingTokenError };
1702 |                         }
1703 | 
1704 |                         const tokenValidation = validateToken(token);
1705 |                         if (tokenValidation) return tokenValidation;
1706 |                         
1707 |                         if (!args || !args.name || !args.content) {
1708 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceError, t.missingNameAndContent, 'error');
1709 |                             return {
1710 |                               status: 'E30-R-3001',
1711 |                               message: t.missingNameAndContent
1712 |                             };
1713 |                         }
1714 | 
1715 |                         const { name, content, groups } = args;
1716 | 
1717 |                         try {
1718 |                             // Token im Header setzen
1719 |                             this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
1720 | 
1721 |                             // Gruppenvalidierung vorab durchführen
1722 |                             if (groups && groups.length > 0) {
1723 | 																if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceGroupCheck, t.checkingGroups.replace('${groups}', JSON.stringify(groups)),  'info');
1724 | 
1725 |                                 const response = await this.axiosInstance.get('/groups');
1726 |                                 const availableGroups = response.data?.data?.assignableGroups || [];
1727 | 
1728 |                                 // Ungültige Gruppen ermitteln
1729 |                                 const invalidGroups = groups.filter(group => !availableGroups.includes(group));
1730 |                                 if (invalidGroups.length > 0) {
1731 |                                     if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceInvalidGroups, t.invalidGroups.replace('${groups}', invalidGroups.join(', ')), 'error');
1732 |                                     return {
1733 |                                         status: 'E30-R-3002',
1734 |                                         message: t.invalidGroups.replace('${groups}', invalidGroups.join(', ')),
1735 |                                     };
1736 |                                 }
1737 |                             }
1738 | 
1739 |                             // API-Aufruf zur Erstellung der Quelle
1740 |                             const createSourceResponse = await this.axiosInstance.post(
1741 |                                 '/sources',
1742 |                                 { name, content, groups },
1743 |                                 { headers: { Authorization: `Bearer ${token}` } }
1744 |                             );
1745 | 
1746 |                             // Loggen der erfolgreichen Erstellung der Quelle
1747 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceSuccess, t.createSourceSuccess.replace('${data}', JSON.stringify(createSourceResponse.data)), 'info');
1748 | 
1749 |                             // Erfolgsantwort
1750 |                             return {
1751 |                                 status: createSourceResponse.data?.status || 'ok',
1752 |                                 message: createSourceResponse.data?.message || 'Quelle erfolgreich erstellt.',
1753 |                                 data: createSourceResponse.data?.data,
1754 |                             };
1755 |                         } catch (error) {
1756 |                             const createSourceError = error.response?.data || error.message;
1757 |                             // Loggen des Fehlers bei der Erstellung der Quelle
1758 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceError, t.createSourceError.replace('${error}', createSourceError), 'error');
1759 | 
1760 |                             // Fehlerhafte Antwort
1761 |                             if (error.response) {
1762 | 								if (!isanonymousModeEnabled) {
1763 | 									logEvent(
1764 | 										'server',
1765 | 										'swreg',
1766 | 										l.prefix_create_sourceResponseError,
1767 | 										t.returnStatus.replace('${Status}', error.response.status) +
1768 | 										`, Data: ${JSON.stringify(error.response.data)}`,
1769 | 										'error'
1770 | 									);
1771 | 								}
1772 |                                 return {
1773 |                                     status: 'E30-R-3003',
1774 |                                     message: 'Ein Fehler ist aufgetreten.',
1775 |                                     details: {
1776 |                                         status: error.response.status,
1777 |                                         headers: error.response.headers,
1778 |                                         data: error.response.data,
1779 |                                     },
1780 |                                 };
1781 |                             } else if (error.request) {
1782 |                                 if (!isanonymousModeEnabled) logEvent(
1783 |                                   'server',
1784 |                                   'swreg',
1785 |                                   l.prefix_create_sourceNoResponse,
1786 |                                   t.noServerResponse + ` ${JSON.stringify(error.request)}`,
1787 |                                   'error'
1788 |                                 );
1789 | 
1790 |                                 return {
1791 |                                     status: 'E30-R-3004',
1792 |                                     message: t.noServerResponse,
1793 |                                     details: { request: error.request },
1794 |                                 };
1795 |                             } else {
1796 |                                 if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_create_sourceUnknownError, t.create_sourceUnknownError.replace('${error}', error.message), 'error');
1797 |                                 return {
1798 |                                     status: 'E30-R-3005',
1799 |                                     message: error.message || t.unknownError,
1800 |                                 };
1801 |                             }
1802 |                         }
1803 |                     }
1804 |                     /* 3.1 Get Source #################################################################################*/
1805 |                     case 'get_source': {
1806 |                         const disabledResponse = checkToolEnabled('get_source');
1807 |                         if (disabledResponse) return disabledResponse;
1808 | 
1809 |                         const args = request.params.arguments;
1810 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_sourceRequest, t.makingGetSourceRequest.replace('${args}', JSON.stringify(args, null, 2)), 'info');
1811 | 
1812 |                         try {
1813 |                             const getSourceResponse = await this.axiosInstance.get(`/sources/${args.sourceId}`);
1814 |                             // Loggen der erhaltenen Quellenantwort
1815 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_sourceSuccess, t.gotGetSourceResponse.replace('${data}', JSON.stringify(getSourceResponse.data, null, 2)), 'info');
1816 |                             return {
1817 |                                 content: [
1818 |                                     {
1819 |                                         type: 'text',
1820 |                                         text: JSON.stringify(getSourceResponse.data, null, 2)
1821 |                                     }
1822 |                                 ]
1823 |                             };
1824 |                         } catch (error) {
1825 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_get_sourceError, t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)), 'error');
1826 |                             return {
1827 |                                 status: 'E31-R-3101',
1828 |                                 message: t.apiErrorDetails
1829 |                                     .replace('${status}', error.response?.status || 'E31-R-3151')
1830 |                                     .replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)),
1831 |                             };
1832 |                         }
1833 |                     }
1834 |                     /* 3.2 List Sources ##############################################################################*/
1835 |                     case 'list_sources': {
1836 |                         const disabledResponse = checkToolEnabled('list_sources');
1837 |                         if (disabledResponse) return disabledResponse;
1838 | 
1839 |                         const args = request.params.arguments;
1840 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_list_sourcesRequest, t.makingListSourcesRequest.replace('${args}', JSON.stringify(args, null, 2)), 'info');
1841 | 
1842 |                         try {
1843 |                             const listSourcesResponse = await this.axiosInstance.post('/sources/groups', {
1844 |                                 groupName: args.groupName
1845 |                             });
1846 |                             // Loggen der erhaltenen Quellenliste
1847 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_list_sourcesSuccess, t.gotListSourcesResponse.replace('${data}', JSON.stringify(listSourcesResponse.data, null, 2)), 'info');
1848 |                             return {
1849 |                                 content: [
1850 |                                     {
1851 |                                         type: 'text',
1852 |                                         text: JSON.stringify(listSourcesResponse.data, null, 2)
1853 |                                     }
1854 |                                 ]
1855 |                             };
1856 |                         } catch (error) {
1857 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_list_sourcesError, t.apiRequestError.replace('${error}', error.message || JSON.stringify(error, null, 2)), 'error');
1858 |                             return {
1859 |                               status: 'E32-R-3210',
1860 |                               message: error.response?.data?.message || t.fetchSourcesError,
1861 |                             };
1862 |                         }
1863 |                     }
1864 |                     /* 3.3 Edit Source ################################################################################*/
1865 |     				case 'edit_source': {
1866 |     					const disabledResponse = checkToolEnabled('edit_source');
1867 |     					if (disabledResponse) return disabledResponse;
1868 | 
1869 |                         const { token, arguments: args } = request.params;
1870 |                         const { sourceId, title, content, groups } = args;
1871 | 
1872 |                         const tokenValidation = validateToken(token);
1873 |                         if (tokenValidation) return tokenValidation;
1874 | 
1875 |                         // Validierung: Erforderliche Parameter
1876 |                         if (!sourceId) {
1877 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_edit_sourceError, t.sourceIdRequiredEditSource, 'error');
1878 |                             return {
1879 |                                 data: {},
1880 |                                 message: t.missingParameterError.replace('${parameter}', 'sourceId'),
1881 |                                 status: 'E33-R-3300', // Bad Request
1882 |                             };
1883 |                         }
1884 | 
1885 |                         // Loggen des Beginns der Quellenbearbeitung
1886 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_edit_source, t.editSourceLog.replace('${sourceId}', sourceId).replace('${title}', title || 'unverändert'), 'info');
1887 | 
1888 |                         try {
1889 |                             // Nur Felder senden, die tatsächlich aktualisiert werden sollen
1890 |                             const payload = {};
1891 |                             if (title) payload.title = title;
1892 |                             if (content) payload.content = content;
1893 |                             if (groups) payload.groups = groups;
1894 | 
1895 |                             const editSourceResponse = await this.axiosInstance.patch(
1896 |                                 `/sources/${sourceId}`,
1897 |                                 payload,
1898 |                                 {
1899 |                                     headers: {
1900 |                                         Authorization: `Bearer ${token}` // Nutze den bereitgestellten Token
1901 |                                     },
1902 |                                 }
1903 |                             );
1904 | 
1905 |                             // Loggen der erfolgreichen Quellenbearbeitung
1906 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_edit_sourceSuccess, t.editSourceSuccess.replace('${data}', JSON.stringify(editSourceResponse.data, null, 2)), 'info');
1907 | 
1908 |                             // Erfolgreiche Antwort
1909 |                             return {
1910 |                                 data: editSourceResponse.data?.data || {}, // Optionale Daten aus der API
1911 |                                 message: editSourceResponse.data?.message || 'Quelle erfolgreich bearbeitet.',
1912 |                                 status: editSourceResponse.status || 200, // OK
1913 |                             };
1914 |                         } catch (error) {
1915 |                             const editSourceError = error.message || JSON.stringify(error.response?.data);
1916 |                             // Loggen des Fehlers bei der Quellenbearbeitung
1917 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_edit_sourceError, t.editSourceError.replace('${error}', editSourceError), 'error');
1918 | 
1919 |                             // Fehlerhafte Antwort
1920 |                             return {
1921 |                                 data: {},
1922 |                                 message: error.response?.data?.message || 'Bearbeiten der Quelle fehlgeschlagen. Bitte versuchen Sie es später erneut.',
1923 |                                 status: error.response?.status || 'E33-R-3301', // Internal Server Error
1924 |                             };
1925 |                         }
1926 |                     }                   
1927 |                     /* 3.4 Delete Source ##############################################################################*/
1928 |                     case 'delete_source': {
1929 |                         const disabledResponse = checkToolEnabled('delete_source');
1930 |                         if (disabledResponse) return disabledResponse;
1931 | 
1932 |                         const { token, arguments: args } = request.params;
1933 | 
1934 |                         // Validierung: Token erforderlich
1935 |                         const tokenValidation = validateToken(token);
1936 |                         if (tokenValidation) return tokenValidation;
1937 | 
1938 |                         const { sourceId } = args;
1939 | 
1940 |                         // Validierung: sourceId erforderlich
1941 |                         if (!sourceId) {
1942 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_sourceError, t.sourceIdRequiredDeleteSource, 'error');
1943 |                             return {
1944 |                                 data: {},
1945 |                                 message: t.missingParameterError.replace('${parameter}', 'sourceId'),
1946 |                                 status: 'E34-R-3400', // Bad Request
1947 |                             };
1948 |                         }
1949 | 
1950 |                         try {
1951 |                             // API-Aufruf: Quelle löschen
1952 |                             const deleteResponse = await this.axiosInstance.delete(`/sources/${sourceId}`, {
1953 |                                 headers: { Authorization: `Bearer ${token}` },
1954 |                             });
1955 | 
1956 |                             // Loggen der erfolgreichen Quellenlöschung
1957 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_sourceSuccess, t.deleteSourceSuccess.replace('${data}', JSON.stringify(deleteResponse.data, null, 2)), 'info');
1958 | 
1959 |                             // Erfolgreiche Antwort
1960 |                             return {
1961 |                                 data: deleteResponse.data?.data || {}, // Optionale Daten aus der API
1962 |                                 message: deleteResponse.data?.message || 'Quelle erfolgreich gelöscht.',
1963 |                                 status: deleteResponse.status || 200, // OK
1964 |                             };
1965 |                         } catch (error) {
1966 |                             // Loggen des Fehlers bei der Quellenlöschung
1967 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_sourceError, t.deleteSourceError.replace('${error}', error.message || JSON.stringify(error.response?.data)), 'error');
1968 |                             if (axios.isAxiosError(error)) {
1969 |                                 const message = error.response?.data?.message || 'Fehler beim Löschen der Quelle.';
1970 |                                 if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_apiRequestError, t.apiErrorDetails.replace('${status}', error.response?.status || 'E41-R-4100').replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)), 'error');
1971 |                                 return {
1972 |                                     content: [
1973 |                                         {
1974 |                                             type: 'text',
1975 |                                             text: `API-Fehler: ${message}`,
1976 |                                         },
1977 |                                     ],
1978 |                                     isError: true,
1979 |                                 };
1980 |                             }
1981 |                             throw new McpError(
1982 |                                 ErrorCode.InternalError,
1983 |                                 t.deleteSourceInternalError
1984 |                             );
1985 |                         }
1986 |                     }
1987 |                     /* 4.0 List Groups ################################################################################*/
1988 |                     case 'list_groups': {
1989 |                         const disabledResponse = checkToolEnabled('list_groups');
1990 |                         if (disabledResponse) return disabledResponse;
1991 | 
1992 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_list_groupsRequest, t.makingListGroupsRequest, 'info');
1993 | 
1994 |                         try {
1995 |                             const listGroupsResponse = await this.axiosInstance.get('/groups');
1996 |                             // Loggen der erfolgreichen Gruppenliste
1997 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_list_groupsSuccess, t.gotListGroupsResponse.replace('${data}', JSON.stringify(listGroupsResponse.data)), 'info');
1998 |                             return {
1999 |                                 content: [
2000 |                                     {
2001 |                                         type: 'text',
2002 |                                         text: JSON.stringify(listGroupsResponse.data, null, 2)
2003 |                                     }
2004 |                                 ]
2005 |                             };
2006 |                         } catch (error) {
2007 |                             const fetchGroupsError = error.message || JSON.stringify(error.response?.data);
2008 |                             // Loggen des Fehlers beim Abrufen der Gruppen
2009 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_list_groupsError, t.fetchGroupsError.replace('${error}', fetchGroupsError), 'error');
2010 |                             return {
2011 |                                 status: 'E40-R-4051',
2012 |                                 message: `${t.fetchGroupsErrorPrefix} ${error.response?.data?.message || t.unknownError}`,
2013 |                             };
2014 |                         }
2015 |                     }
2016 |                     /* 4.1 Store Group ################################################################################*/
2017 |                     case 'store_group': {
2018 |                         const disabledResponse = checkToolEnabled('store_group');
2019 |                         if (disabledResponse) return disabledResponse;
2020 | 
2021 |                         const args = request.params.arguments;
2022 | 
2023 |                         if (!args || !args.groupName) {
2024 |                             throw new McpError(
2025 |                               ErrorCode.InvalidRequest,
2026 |                               t.missingGroupParameterStore
2027 |                             );
2028 |                         }
2029 | 
2030 |                         // Loggen des Beginns der Gruppenspeicherung
2031 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_groupRequest, t.storeGroupLog
2032 |                             .replace('${groupName}', args.groupName)
2033 |                             .replace('${description}', args.description || t.noDescriptionProvided), 'info');
2034 | 
2035 |                         try {
2036 |                             const storeGroupResponse = await this.axiosInstance.post('/groups', {
2037 |                                 groupName: args.groupName,
2038 |                                 description: args.description || ''
2039 |                             });
2040 |                             // Loggen der erfolgreichen Gruppenspeicherung
2041 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_groupSuccess, t.storeGroupSuccess.replace('${data}', JSON.stringify(storeGroupResponse.data, null, 2)), 'info');
2042 | 
2043 |                             return {
2044 |                                 content: [
2045 |                                     {
2046 |                                         type: 'text',
2047 |                                         text: `Gruppe "${args.groupName}" erfolgreich erstellt mit ID: ${storeGroupResponse.data.id}`
2048 |                                     }
2049 |                                 ]
2050 |                             };
2051 |                         } catch (error) {
2052 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_groupError, t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)), 'error');
2053 |                             if (axios.isAxiosError(error)) {
2054 |                                 const message = error.response?.data?.message ?? error.message;
2055 |                                 if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_apiRequestError, t.apiErrorDetails.replace('${status}', error.response?.status || 'E41-R-4100').replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)), 'error');
2056 |                                 return {
2057 |                                     content: [
2058 |                                         {
2059 |                                             type: 'text',
2060 |                                             text: `API-Fehler: ${message}`
2061 |                                         }
2062 |                                     ],
2063 |                                     isError: true
2064 |                                 };
2065 |                             }
2066 |                             throw error;
2067 |                         }
2068 |                     };
2069 |                     /* 4.2 Delete Group ###############################################################################*/
2070 |                     case 'delete_group': {
2071 |                         const disabledResponse = checkToolEnabled('delete_group');
2072 |                         if (disabledResponse) return disabledResponse;
2073 | 
2074 |                         const { groupName } = request.params.arguments; // Extrahiere die Gruppe
2075 |                         if (!groupName) {
2076 |                             throw new McpError(
2077 |                                 ErrorCode.InvalidRequest,
2078 |                                 t.missingGroupParameterDelete
2079 |                             );
2080 |                         }
2081 | 
2082 |                         // Loggen des Beginns der Gruppenlöschung
2083 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_groupRequest, t.deleteGroupLog.replace('${groupName}', groupName), 'info');
2084 | 
2085 |                         try {
2086 |                             // API-Aufruf mit dem notwendigen JSON-Body
2087 |                             const deleteGroupResponse = await this.axiosInstance.delete('/groups', {
2088 |                                 data: { groupName }, // JSON-Body für den DELETE-Request
2089 |                             });
2090 | 
2091 |                             // Loggen der erfolgreichen Gruppenlöschung
2092 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_groupSuccess, t.deleteGroupSuccessLog.replace('${data}', JSON.stringify(deleteGroupResponse.data)), 'info');
2093 | 
2094 |                             return {
2095 |                                 content: [
2096 |                                     {
2097 |                                         type: 'text',
2098 |                                         text: `Gruppe "${groupName}" wurde erfolgreich gelöscht.`,
2099 |                                     },
2100 |                                 ],
2101 |                             };
2102 |                         } catch (error) {
2103 |                             // Loggen des Fehlers bei der Gruppenlöschung
2104 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_groupError, t.apiRequestError.replace('${error}', error.message || JSON.stringify(error.response?.data)), 'error');
2105 |                             if (axios.isAxiosError(error)) {
2106 |                                 const message = error.response?.data?.message || 'Fehler beim Löschen der Gruppe.';
2107 |                                 if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_apiRequestError, t.apiErrorDetails.replace('${status}', error.response?.status || 'E41-R-4100').replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)), 'error');
2108 |                                 return {
2109 |                                     content: [
2110 |                                         {
2111 |                                             type: 'text',
2112 |                                             text: `API-Fehler: ${message}`,
2113 |                                         },
2114 |                                     ],
2115 |                                     isError: true,
2116 |                                 };
2117 |                             }
2118 |                             throw new McpError(
2119 |                                 ErrorCode.InternalError,
2120 |                                 t.deleteGroupInternalError
2121 |                             );
2122 |                         }
2123 |                     }
2124 |                     /* 5.0 Store User ################################################################################*/
2125 |                     case 'store_user': {
2126 |                         const disabledResponse = checkToolEnabled('store_user');
2127 |                         if (disabledResponse) return disabledResponse;
2128 | 
2129 |                         // Token und Argumente aus request.params entnehmen
2130 |                         const { token, arguments: args } = request.params;
2131 | 
2132 |                         // Token validieren
2133 |                         const tokenValidation = validateToken(token);
2134 |                         if (tokenValidation) return tokenValidation;
2135 | 
2136 |                         // Erforderliche Felder prüfen
2137 |                         if (!args || !args.name || !args.email || !args.password) {
2138 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_userError, t.missingNameEmailPwd, 'error');
2139 |                             return {
2140 |                               status: 'E50-R-5000',
2141 |                               message: t.missingNameEmailPwd
2142 |                             };
2143 |                         }
2144 | 
2145 |                         try {
2146 |                             // Benutzer anlegen
2147 |                             const response = await this.axiosInstance.post(
2148 |                                 '/users',
2149 |                                 {
2150 |                                     name: args.name,
2151 |                                     email: args.email,
2152 |                                     password: args.password,
2153 |                                     language: args.language || 'en',
2154 |                                     timezone: args.timezone || 'Europe/Berlin',
2155 |                                     roles: args.roles || [],
2156 |                                     groups: args.groups || [],
2157 |                                     usePublic: args.usePublic || false
2158 |                                 },
2159 |                                 {
2160 |                                     headers: {
2161 |                                         Authorization: `Bearer ${token}`
2162 |                                     }
2163 |                                 }
2164 |                             );
2165 | 
2166 |                             // Loggen der erfolgreichen Benutzererstellung
2167 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_userSuccess, t.createUserSuccess.replace('${data}', JSON.stringify(createUserResponse.data)), 'info');
2168 | 
2169 |                             // Erfolgreiche Antwort
2170 |                             return {
2171 |                                 status: response.data?.status || 'ok',
2172 |                                 message: response.data?.message || 'Benutzer erfolgreich erstellt.',
2173 |                                 data: response.data?.data
2174 |                             };
2175 |                         } catch (error) {
2176 |                             // Loggen des Fehlers bei der Benutzererstellung
2177 | 							
2178 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_userError, t.createUserError.replace('${error}', error.response?.data || error.message), 'error');
2179 |                             return {
2180 |                                 status: error.response?.status || 'E50-R-5001',
2181 |                                 message: error.response?.data?.message || t.createUserError.replace('${error}', error.response?.data || error.message),
2182 |                             };
2183 |                         }
2184 |                     }
2185 |                     /* 5.1 Edit User #################################################################################*/
2186 |                     case 'edit_user': {
2187 |                         const disabledResponse = checkToolEnabled('edit_user');
2188 |                         if (disabledResponse) return disabledResponse;
2189 | 
2190 |                         const { token, arguments: args } = request.params;
2191 |                         const tokenValidation = validateToken(token);
2192 |                         if (tokenValidation) return tokenValidation;
2193 | 
2194 |                         // Mindestens die E-Mail muss angegeben sein, um den User zu identifizieren
2195 |                         if (!args || !args.email) {
2196 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_edit_userError, t.emailRequiredForEdit, 'error');
2197 |                             return {
2198 |                                 status: 'E51-R-5100',
2199 |                                 message: t.emailRequiredForEdit
2200 |                             };
2201 |                         }
2202 | 
2203 |                         try {
2204 |                             // Nur Felder senden, die tatsächlich aktualisiert werden sollen
2205 |                             const payload = {};
2206 |                             if (args.name) payload.name = args.name;
2207 |                             if (args.password) payload.password = args.password;
2208 |                             if (args.language) payload.language = args.language;
2209 |                             if (args.timezone) payload.timezone = args.timezone;
2210 |                             if (Array.isArray(args.roles)) payload.roles = args.roles;
2211 |                             if (Array.isArray(args.groups)) payload.groups = args.groups;
2212 |                             if (typeof args.usePublic === 'boolean') payload.usePublic = args.usePublic;
2213 | 
2214 |                             // E-Mail ist Pflicht, um den Benutzer auf dem Server zu finden
2215 |                             payload.email = args.email;
2216 | 
2217 |                             const response = await this.axiosInstance.patch(
2218 |                                 '/users',
2219 |                                 payload,
2220 |                                 {
2221 |                                     headers: { Authorization: `Bearer ${token}` }
2222 |                                 }
2223 |                             );
2224 | 
2225 |                             // Loggen der erfolgreichen Benutzerbearbeitung
2226 | 							if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_store_userSuccess, t.editUserSuccess.replace('${data}', JSON.stringify(response.data)), 'info');
2227 |                        
2228 |                             return {
2229 |                                 status: response.data?.status || 'ok',
2230 |                                 message: response.data?.message || t.editUserSuccess.replace('${data}', JSON.stringify(response.data)),
2231 |                                 data: response.data?.data
2232 |                             };
2233 |                         } catch (error) {
2234 |                             const editUserError = error.response?.data || error.message;
2235 |                             // Loggen des Fehlers bei der Benutzerbearbeitung
2236 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_edit_userError, t.editUserError.replace('${error}', editUserError), 'error');
2237 |                             return {
2238 |                                 status: error.response?.status || 'E51-R-5101',
2239 |                                 message: error.response?.data?.message || 'Fehler beim Bearbeiten des Benutzers.'
2240 |                             };
2241 |                         }
2242 |                     }
2243 |                     /* 5.2 Delete User ################################################################################*/
2244 |                     case 'delete_user': {
2245 |                         const disabledResponse = checkToolEnabled('delete_user');
2246 |                         if (disabledResponse) return disabledResponse;
2247 | 
2248 |                         const { token, arguments: args } = request.params;
2249 |                         const tokenValidation = validateToken(token);
2250 |                         if (tokenValidation) return tokenValidation;
2251 | 
2252 |                         // E-Mail ist nötig, um den Benutzer zu löschen
2253 |                         if (!args || !args.email) {
2254 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_userError, t.emailRequiredForDelete, 'error');
2255 |                             return {
2256 |                                 status: 'E52-R-5200',
2257 |                                 message: t.emailRequiredForDelete
2258 |                             };
2259 |                         }
2260 | 
2261 |                         try {
2262 |                             // DELETE-Anfrage mit JSON-Body
2263 |                             const response = await this.axiosInstance.delete(
2264 |                                 '/users',
2265 |                                 {
2266 |                                     data: { email: args.email },
2267 |                                     headers: { Authorization: `Bearer ${token}` }
2268 |                                 }
2269 |                             );
2270 | 
2271 |                             // Loggen der erfolgreichen Benutzerlöschung
2272 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_userSuccess, t.deleteUserSuccess.replace('${data}', JSON.stringify(response.data, null, 2)), 'info');
2273 | 
2274 |                             return {
2275 |                                 status: response.data?.status || 'ok',
2276 |                                 message: response.data?.message || 'Benutzer erfolgreich gelöscht.',
2277 |                                 data: response.data?.data
2278 |                             };
2279 |                         } catch (error) {
2280 |                             // Loggen des Fehlers bei der Benutzerlöschung
2281 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_delete_userError, t.deleteUserError.replace('${error}', error.response?.data || error.message), 'error');
2282 |                             return {
2283 |                                 status: error.response?.status || 'E52-R-5201',
2284 |                                 message: error.response?.data?.message || 'Fehler beim Löschen des Benutzers.'
2285 |                             };
2286 |                         }
2287 |                     }
2288 |                     /* 5.3 Reactivate User ################################################################################*/
2289 |                     case 'reactivate_user': {
2290 |                         const disabledResponse = checkToolEnabled('reactivate_user');
2291 |                         if (disabledResponse) return disabledResponse;
2292 | 
2293 |                         const { token, arguments: args } = request.params;
2294 |                         const tokenValidation = validateToken(token);
2295 |                         if (tokenValidation) return tokenValidation;
2296 | 
2297 |                         // E-Mail ist erforderlich, um einen Benutzer zu reaktivieren
2298 |                         if (!args || !args.email) {
2299 |                             if (!isanonymousModeEnabled) {
2300 |                                 logEvent('server', 'swreg', l.prefix_reactivate_userError, t.emailRequiredForReactivate, 'error');
2301 |                             }
2302 |                             return {
2303 |                                 status: 'E53-R-5300',
2304 |                                 message: t.emailRequiredForReactivate
2305 |                             };
2306 |                         }
2307 | 
2308 |                         try {
2309 |                             // POST-Anfrage mit JSON-Body für die Reaktivierung des Benutzers
2310 |                             const response = await this.axiosInstance.post(
2311 |                                 '/api/v1/users/reactivate',
2312 |                                 { email: args.email },
2313 |                                 {
2314 |                                     headers: { 
2315 |                                         Authorization: `Bearer ${token}`,
2316 |                                         Accept: 'application/json'
2317 |                                     }
2318 |                                 }
2319 |                             );
2320 | 
2321 |                             // Loggen der erfolgreichen Benutzerreaktivierung
2322 |                             if (!isanonymousModeEnabled) {
2323 |                                 logEvent('server', 'swreg', l.prefix_reactivate_userSuccess, `Benutzer erfolgreich reaktiviert: ${JSON.stringify(response.data)}`, 'info');
2324 |                             }
2325 | 
2326 |                             return {
2327 |                                 status: response.data?.status || 'ok',
2328 |                                 message: response.data?.message || 'Benutzer erfolgreich reaktiviert.',
2329 |                                 data: response.data?.data
2330 |                             };
2331 |                         } catch (error) {
2332 |                             // Loggen des Fehlers bei der Benutzerreaktivierung
2333 |                             if (!isanonymousModeEnabled) {
2334 |                                 logEvent('server', 'swreg', l.prefix_reactivate_userError, t.reactivateUserError.replace('${error}', error.response?.data || error.message), 'error');
2335 |                             }
2336 |                             return {
2337 |                                 status: error.response?.status || 'E53-R-5301',
2338 |                                 message: error.response?.data?.message || 'Fehler bei der Reaktivierung des Benutzers.'
2339 |                             };
2340 |                         }
2341 |                     }
2342 |                    /* 6.0 OpenAPI Compatible API Chat #######################################################################################*/
2343 |                     case 'oai_comp_api_chat': {
2344 |                         const disabledResponse = checkToolEnabled('oai_comp_api');
2345 |                         if (disabledResponse) return disabledResponse;
2346 | 
2347 |                         const { token, arguments: args } = request.params;
2348 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chat, t.extractedToken.replace('${token}', token), 'info');
2349 | 
2350 |                         // Token prüfen und validieren
2351 |                         if (!token) {
2352 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatError, t.noTokenError, 'error');
2353 |                             return { status: 'E60-R-6000', message: t.missingTokenError };
2354 |                         }
2355 |                         const tokenValidation = validateToken(token);
2356 |                         if (tokenValidation) return tokenValidation;
2357 | 
2358 | 
2359 |                         // Argument-Validierung
2360 |                         if (!args || !args.question) {
2361 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatError, t.missingArgumentsError.replace('${args}', JSON.stringify(args)), 'error');
2362 |                             return {
2363 |                                 status: 'error',
2364 |                                 message: t.missingArgumentsError.replace('${args}', JSON.stringify(args)),
2365 |                             };
2366 |                         }
2367 | 
2368 |                         const { question, usePublic, groups, language } = args;
2369 | 
2370 |                         // Konflikt zwischen `usePublic` und `groups` lösen
2371 |                         if (usePublic && groups && groups.length > 0) {
2372 |                             if (!isanonymousModeEnabled) logEvent('system', 'swreg', l.prefix_chatWarning, t.publicGroupsConflictWarning, 'warn');
2373 |                             args.usePublic = false;
2374 |                         }
2375 | 
2376 |                         try {
2377 |                             // Loggen der Chat-Anfrage
2378 |                             if (!isanonymousModeEnabled) logEvent('oaichat', 'swreg', l.prefix_chatRequest, t.sendingChatRequest
2379 |                                 .replace('${question}', question)
2380 |                                 .replace('${usePublic}', usePublic)
2381 |                                 .replace('${groups}', JSON.stringify(groups))
2382 |                                 .replace('${language}', language), 'info');
2383 | 
2384 |                             const response = await this.axiosInstance.post(
2385 |                                 '/chats',
2386 |                                 {
2387 |                                     question,
2388 |                                     usePublic: usePublic || false,
2389 |                                     groups: Array.isArray(groups) ? groups : [groups],
2390 |                                     language: language || 'de',
2391 |                                 },
2392 |                                 { headers: { Authorization: `Bearer ${token}` } }
2393 |                             );
2394 | 
2395 |                             const data = response.data?.data || {};
2396 |                             // Loggen der erfolgreichen Chat-Antwort
2397 |                             if (!isanonymousModeEnabled) logEvent('server', 'oareg', l.prefix_chatSuccess, t.chatResponseSuccess.replace('${data}', JSON.stringify(data)), 'info');
2398 | 
2399 |                             // Erfolgsantwort mit Status und Daten
2400 |                             return {
2401 |                                 status: response.data?.status || 'ok',
2402 |                                 message: response.data?.message || 'Chat erfolgreich.',
2403 |                                 content: {
2404 |                                     chatId: data.chatId,
2405 |                                     answer: data.answer,
2406 |                                     sources: data.sources || [],
2407 |                                 },
2408 |                             };
2409 |                         } catch (error) {
2410 |                             const chatApiErrorMessage = error.message || error.response?.data;
2411 |                             // Loggen des Fehlers bei der Chat-API-Anfrage
2412 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_chatApiError, t.chatApiError.replace('${error}', chatApiErrorMessage), 'error');
2413 | 
2414 |                             // Fehlerantwort mit Status und Nachricht
2415 |                             return {
2416 |                                 status: error.response?.status || 'E60-R-6002',
2417 |                                 message: error.response?.data?.message || t.chatApiErrorDefault,
2418 |                             };
2419 |                         }
2420 |                     }
2421 |                     /* 6.1 Continue Chat ##############################################################################*/
2422 |                     case 'oai_comp_api_continue_chat': {
2423 |                         const disabledResponse = checkToolEnabled('oai_comp_api');
2424 |                         if (disabledResponse) return disabledResponse;
2425 | 
2426 |                         const args = request.params.arguments;
2427 | 
2428 |                         if (!args || !args.chatId || !args.question) {
2429 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chatError, t.missingChatParams, 'error');
2430 |                             return {
2431 |                               status: 'E21-R-6100',
2432 |                               message: t.missingChatParams
2433 |                             };
2434 |                         }
2435 | 
2436 |                         const { chatId, question } = args;
2437 |                         if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chat, t.conversationContinuation.replace('${chatId}', chatId), 'info');
2438 | 
2439 |                         try {
2440 |                             const continueChatResponse = await this.axiosInstance.patch(`/chats/${chatId}`, {
2441 |                                 question: question,
2442 |                             });
2443 |                             // Loggen der erfolgreichen Fortsetzung der Konversation
2444 |                             if (!isanonymousModeEnabled) logEvent('server', 'oareg', l.prefix_continue_chatSuccess, t.conversationSuccess.replace('${data}', JSON.stringify(continueChatResponse.data, null, 2)), 'info');
2445 |                             return {
2446 |                                 content: {
2447 |                                     chatId:  continueChatResponse.data.data.chatId,
2448 |                                     answer:  continueChatResponse.data.data.answer,
2449 |                                     sources: continueChatResponse.data.sources || [],
2450 |                                     message: continueChatResponse.data.message,
2451 |                                     status:  continueChatResponse.data.status,
2452 |                                 },
2453 |                             };
2454 |                         } catch (error) {
2455 |                             if (!isanonymousModeEnabled) logEvent('server', 'swreg', l.prefix_continue_chatError, t.apiRequestError.replace('${error}', error.message), 'error');
2456 |                             return {
2457 |                               status: error.response?.status || 'E61-R-6101',
2458 |                               message: error.response?.data?.message || t.continueConversationError,
2459 |                             };
2460 |                         }
2461 |                     }
2462 |                     default:
2463 |                         // Loggen unbekannter Befehle
2464 |                         if (!isanonymousModeEnabled) logEvent(
2465 |                             'system',
2466 |                             'swreg',
2467 |                             l.prefix_unknownCommand,
2468 |                             t.unknownCommandError.replace('${cmd}', request.params.name),
2469 |                             'warn'
2470 |                         );
2471 |                         throw new McpError(
2472 |                             ErrorCode.MethodNotFound,
2473 |                             t.unknownTool.replace('${toolName}', request.params.name)
2474 |                         );
2475 |                     }
2476 |             }
2477 |             catch (error) {
2478 |                 if (!isanonymousModeEnabled) logEvent('system', 'swreg', l.prefix_Unhandled_Error, t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)), 'error');
2479 |                 if (axios.isAxiosError(error)) {
2480 |                     const message = error.response?.data?.message ?? error.message;
2481 |                     if (!isanonymousModeEnabled) logEvent('system', 'swreg', l.prefix_apiRequestError, t.apiErrorDetails.replace('${status}', error.response?.status || 'Unknown').replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)), 'error');
2482 |                     return {
2483 |                         content: [
2484 |                             {
2485 |                                 type: 'text',
2486 |                                 text: `API error: ${message}`
2487 |                             }
2488 |                         ],
2489 |                         isError: true
2490 |                     };
2491 |                 }
2492 |                 throw error;
2493 |             }
2494 |         });
2495 |     }
2496 | 
2497 |  /* ##################################################################################################
2498 |    # MESSAGE HANDLER
2499 |    ##################################################################################################*/
2500 | async run() {
2501 |     const isPortInUse = (port) => new Promise((resolve, reject) => {
2502 |         const tester = net.createServer()
2503 |             .once('error', (err) => (err.code === 'EADDRINUSE' ? resolve(true) : reject(err)))
2504 |             .once('listening', () => tester.once('close', () => resolve(false)).close())
2505 |             .listen(port);
2506 |     });
2507 | 
2508 |     const PORT = Port;
2509 |     if (await isPortInUse(PORT)) {
2510 |         if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_Port_Check, t.portInUse.replace('${PORT}', PORT), 'error');
2511 |         throw new Error(t.portInUse.replace('${PORT}', PORT));
2512 |     }
2513 | 
2514 |     const transport = new TcpServerTransport(PORT, enableTLS, sslKeyPath, sslCertPath);
2515 |     await transport.start(async (message) => {
2516 |         try {
2517 |             // if (!isanonymousModeEnabled) logEvent('client', 'swmsg', 'Incoming Message', `Nachricht empfangen: ${JSON.stringify(message)}`, 'info');
2518 | 			if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_Incoming_Message, t.incomingMessage.replace('${MESSAGE}', JSON.stringify(message)), 'info');
2519 | 
2520 |             // Token-Validierung nur durchführen, wenn es nicht der "login"-Befehl ist
2521 |             // if (message.command !== 'login') {
2522 |             //     const tokenValidation = validateToken(message.token);
2523 |             //     if (tokenValidation) return tokenValidation;
2524 |             // }
2525 | 
2526 |             if (!message || typeof message !== 'object') {
2527 |                 throw new McpError(
2528 |                     ErrorCode.InvalidRequest,
2529 |                     t.invalidOrEmptyRequest
2530 |                 );
2531 |             }
2532 | 
2533 |             // Verarbeite verschiedene Anfragen dynamisch
2534 |             if (!message.command) {
2535 |                 throw new McpError(
2536 |                   ErrorCode.InvalidRequest,
2537 |                   t.missingCommandParameter
2538 |                 );
2539 |             }
2540 | 
2541 |             switch (message.command) {
2542 |                 /* 1.0 Login ######################################################################################*/
2543 | 				// clientIP, clientPort, functionName, status, level = 'info')				
2544 |                 case 'login': {
2545 |                     const disabledResponse = checkToolEnabled('login');
2546 |                     if (disabledResponse) return disabledResponse;
2547 | 
2548 |                     // Extrahiere die Argumente aus der Nachricht
2549 |                     const args = getArguments(message);
2550 |                     const { email, password: Pwd } = args;
2551 | 
2552 |                     // Überprüfe, ob die E-Mail und das Passwort vorhanden sind
2553 |                     if (!email || !Pwd) {
2554 |                         if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_loginError, t.loginEmailPasswordRequired, 'error');
2555 |                         return {
2556 |                             status: 'E10-M-1050',
2557 |                             message: t.loginEmailPasswordRequired,
2558 |                         };
2559 |                     }
2560 | 
2561 |                     let password;
2562 | 
2563 |                     // Passwort entschlüsseln, falls erforderlich
2564 |                     if (typeof PwEncryption !== 'undefined' && PwEncryption) {
2565 |                         password = decryptPassword(Pwd);
2566 |                     } else {
2567 |                         password = Pwd;
2568 |                     }
2569 | 
2570 |                     try {
2571 |                         // Login-API aufrufen
2572 |                         const loginResponse = await this.axiosInstance.post('/login', { email, password });
2573 | 
2574 |                         // Loggen des erfolgreichen Logins
2575 |                         if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_loginSuccess, t.loginSuccess.replace('${data}', JSON.stringify(loginResponse.data)), 'info');
2576 | 
2577 |                         // Entfernen des Basic Auth Headers und Setzen des Bearer Tokens
2578 |                         delete this.axiosInstance.defaults.headers.common['Authorization'];
2579 |                         this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${loginResponse.data.data.token}`;
2580 | 
2581 |                         // Token zurückgeben
2582 |                         return {
2583 |                             status: loginResponse.data?.status || 'ok', // Dynamisch, falls der API-Status einheitlich ist
2584 |                             message: loginResponse.data?.message || 'Login erfolgreich.', // API-Nachricht verwenden oder Standardnachricht
2585 |                             token: loginResponse.data?.data?.token, // Token aus API-Antwort
2586 |                         };
2587 |                     } catch (error) {
2588 |                         const errorMessage = error.response?.data || error.message;
2589 |                         // Loggen des Fehlers beim Login
2590 |                         if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_loginError, t.loginError.replace('${error}', errorMessage), 'error');
2591 | 
2592 |                         return {
2593 |                             status: error.response?.status || 'E10-M-1051', // API-Fehlerstatus oder Standardfehlerstatus,
2594 |                             message: error.response?.data || error.message || 'no error message'
2595 |                         };
2596 |                     }
2597 |                 }
2598 |                 /* 1.1 Logout #####################################################################################*/
2599 |                 case 'logout': {
2600 |                     const disabledResponse = checkToolEnabled('logout');
2601 |                     if (disabledResponse) return disabledResponse;
2602 | 
2603 |                     const { token } = message;
2604 |                     
2605 |                     try {
2606 |                         const logoutResponse = await this.axiosInstance.delete('/logout', {
2607 |                             headers: {
2608 |                                 Authorization: `Bearer ${token}`
2609 |                             }
2610 |                         });
2611 | 
2612 | 
2613 |                         // Loggen des erfolgreichen Logouts
2614 |                         if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_logoutSuccess, t.logoutSuccess.replace('${data}', JSON.stringify(logoutResponse.data)), 'info');
2615 | 
2616 |                         return {
2617 |                             data: {}, // Optional: Zusätzliche Daten könnten hier eingefügt werden
2618 |                             status: logoutResponse.data?.status || 'no status', // Dynamisch, falls der API-Status einheitlich ist
2619 |                             message: logoutResponse.data?.message || 'no message', // API-Nachricht verwenden oder Standardnachricht
2620 |                         };
2621 |                     } catch (error) {
2622 |                         const logoutErrorMessage = error.response?.data || error.message;
2623 |                         // Loggen des Fehlers beim Logout
2624 |                         if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_logoutError, t.logoutError.replace('${error}', logoutErrorMessage), 'error');
2625 | 
2626 |                         return {
2627 |                             data: {},
2628 |                             message: error.response?.data || error.message || t.noErrorMessage,
2629 |                             status: error.response?.status || 'E11-R-1150', // Internal Server Error oder spezifischer Statuscode
2630 |                         };
2631 |                     }
2632 |                 }
2633 |                 /* 2.0 Chat #######################################################################################*/
2634 |                 case 'chat': {
2635 |                     const disabledResponse = checkToolEnabled('chat');
2636 |                     if (disabledResponse) return disabledResponse;
2637 | 
2638 |                     const { token, arguments: args } = message;
2639 |                     if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chat, t.extractedToken.replace('${token}', token), 'info');
2640 | 
2641 |                     // Token prüfen und validieren
2642 |                     if (!token) {
2643 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatError, t.noTokenError, 'error');
2644 |                         return { status: 'E20-M-2000', message: t.missingTokenError };
2645 |                     }
2646 | 
2647 |                     // Argument-Validierung
2648 |                     if (!args || !args.question) {
2649 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatError, t.missingArgumentsError.replace('${args}', JSON.stringify(args)), 'error');
2650 |                         return {
2651 |                             status: 'error',
2652 |                             message: t.missingArgumentsError.replace('${args}', JSON.stringify(args)),
2653 |                         };
2654 |                     }
2655 | 
2656 |                     const { question, usePublic, groups, language } = args;
2657 | 
2658 |                     // Konflikt zwischen `usePublic` und `groups` lösen
2659 |                     if (usePublic && groups && groups.length > 0) {
2660 |                         if (!isanonymousModeEnabled) logEvent('system', 'swmsg', l.prefix_chatWarning, t.publicGroupsConflictWarning, 'warn');
2661 |                         args.usePublic = false;
2662 |                     }
2663 | 
2664 |                     try {
2665 |                         // Loggen der Chat-Anfrage
2666 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatRequest, t.sendingChatRequest
2667 |                             .replace('${question}', question)
2668 |                             .replace('${usePublic}', usePublic)
2669 |                             .replace('${groups}', JSON.stringify(groups))
2670 |                             .replace('${language}', language), 'info');
2671 | 
2672 |                         const response = await this.axiosInstance.post(
2673 |                             '/chats',
2674 |                             {
2675 |                                 question,
2676 |                                 usePublic: usePublic || false,
2677 |                                 groups: Array.isArray(groups) ? groups : [groups],
2678 |                                 language: language || 'de',
2679 |                             },
2680 |                             { headers: { Authorization: `Bearer ${token}` } }
2681 |                         );
2682 | 
2683 |                         const data = response.data?.data || {};
2684 |                         // Loggen der erfolgreichen Chat-Antwort
2685 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatSuccess, t.chatResponseSuccess.replace('${data}', JSON.stringify(data)), 'info');
2686 | 
2687 |                         // Erfolgsantwort mit Status und Daten
2688 |                         return {
2689 |                             status: response.data?.status || 'ok',
2690 |                             message: response.data?.message || 'Chat erfolgreich.',
2691 |                             content: {
2692 |                                 chatId: data.chatId,
2693 |                                 answer: data.answer,
2694 |                                 sources: data.sources || [],
2695 |                             },
2696 |                         };
2697 |                     } catch (error) {
2698 |                         const chatApiErrorMessage = error.message || error.response?.data;
2699 |                         // Loggen des Fehlers bei der Chat-API-Anfrage
2700 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatApiError, t.chatApiError.replace('${error}', chatApiErrorMessage), 'error');
2701 | 
2702 |                         // Fehlerantwort mit Status und Nachricht
2703 |                         return {
2704 |                             status: error.response?.status || 'E20-R-2002',
2705 |                             message: error.response?.data?.message || t.chatApiErrorDefault,
2706 |                         };
2707 |                     }
2708 |                 }			
2709 | 				/* 2.1 Continue Chat ##############################################################################*/
2710 | 				case 'continue_chat': {
2711 | 					const disabledResponse = checkToolEnabled('continue_chat');
2712 | 					if (disabledResponse) return disabledResponse;
2713 | 
2714 | 					const token = message.token; // Token direkt extrahieren
2715 | 					const args = message.arguments || {}; // Sichere Extraktion der Argumente
2716 | 					const { chatId, question } = args;
2717 | 
2718 | 					if (!args || !args.chatId || !args.question) {
2719 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_continue_chat, t.missingChatParams, 'error');
2720 | 						return { status: 'E21-M-2150', message: t.missingChatParams };
2721 | 					}
2722 | 
2723 | 					try {
2724 | 						const continueChatResponse = await this.axiosInstance.patch(
2725 | 							`/chats/${chatId}`,
2726 | 							{ question },
2727 | 							{ headers: { Authorization: `Bearer ${token}` } }
2728 | 						);
2729 | 
2730 | 						// Loggen der erfolgreichen Continue-Chat-Antwort
2731 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_continue_chatSuccess, t.conversationSuccess.replace('${data}', JSON.stringify(continueChatResponse.data, null, 2)), 'info');
2732 | 
2733 | 						return {
2734 | 							content: {
2735 | 								chatId: continueChatResponse.data.data.chatId,
2736 | 								answer: continueChatResponse.data.data.answer,
2737 | 								sources: continueChatResponse.data.sources || [],
2738 | 								message: continueChatResponse.data.message,
2739 | 								status: continueChatResponse.data.status,
2740 | 							},
2741 | 						};
2742 | 					} catch (error) {
2743 | 						// Loggen des Fehlers bei der Continue-Chat-API-Anfrage
2744 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_apiRequestError, t.apiRequestError.replace('${error}', error.message), 'error');
2745 | 						return {
2746 | 							status: 'E21-M-2151',
2747 | 							message: error.response?.data?.message || error.message || t.noErrorMessage,
2748 | 						};
2749 | 					}
2750 | 				}
2751 | 				/* 2.2 Get Chat Info ##############################################################################*/
2752 | 				case 'get_chat_info': {
2753 | 					const disabledResponse = checkToolEnabled('get_chat_info');
2754 | 					if (disabledResponse) return disabledResponse;
2755 | 
2756 | 					const { token } = message; // Token direkt aus `message` extrahieren
2757 | 					const args = message.arguments || {}; // Argumente aus `message` extrahieren
2758 | 					const { chatId } = args; // chatId aus den Argumenten extrahieren
2759 | 
2760 | 					if (!chatId) {
2761 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_chat_info, t.missingChatId, 'error');
2762 | 						return { status: 'E22-M-2250', message: t.missingChatId };
2763 | 					}
2764 | 
2765 | 					try {
2766 | 						const response = await this.axiosInstance.get(`/chats/${chatId}`, {
2767 | 							headers: { Authorization: `Bearer ${token}` }
2768 | 						});
2769 | 
2770 | 						const chatData = response.data?.data;
2771 | 
2772 | 						if (!chatData) {
2773 | 							if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_chat_infoError, t.noChatData, 'error');
2774 | 							return {
2775 | 								status: 'E22-M-2251',
2776 | 								message: t.noChatData,
2777 | 							};
2778 | 						}
2779 | 
2780 | 						// Formatiertes Ergebnis zurückgeben 
2781 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_chat_infoSuccess, t.ChatInfoRetrieved.replace('${chatData}', JSON.stringify(chatData)), 'info');
2782 | 
2783 | 						return {
2784 | 							data: {
2785 | 								chatId: chatData.chatId,
2786 | 								title: chatData.title || 'Unbenannter Chat',
2787 | 								language: chatData.language || 'Unbekannt',
2788 | 								groups: chatData.groups || [],
2789 | 								messages: chatData.messages || []
2790 | 							},
2791 | 							message: response.data?.message || 'Erfolgreich abgerufen.'
2792 | 						};
2793 | 					} catch (error) {
2794 | 						const fetchChatErrorMessage = error.message || error.response?.data;
2795 | 						// Loggen des Fehlers beim Abrufen der Chat-Informationen
2796 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_chat_infoError, t.fetchChatInfoError.replace('${error}', fetchChatErrorMessage), 'error');
2797 | 						return {
2798 | 							status: 'E22-M-2252',
2799 | 							message: error.response?.data?.message || t.unknownError,
2800 | 						};
2801 | 					}
2802 | 				}
2803 |                 /* 2.3 Delete All Chats ##############################################################################*/
2804 |                 case 'delete_all_chats': {
2805 |                     const disabledResponse = checkToolEnabled('delete_all_chats');
2806 |                     if (disabledResponse) return disabledResponse;
2807 | 
2808 |                     const token = message?.token;
2809 | 
2810 |                     if (!token) {
2811 |                         return { status: 'E23-M-2301', message: t.missingAuthToken };
2812 |                     }
2813 | 
2814 |                     const tokenValidation = validateToken(token);
2815 |                     if (tokenValidation) return tokenValidation;
2816 | 
2817 |                     try {
2818 |                         const response = await this.axiosInstance.delete('/chats/flush', {
2819 |                             headers: { 
2820 |                                 Authorization: `Bearer ${token}`,
2821 |                                 Accept: 'application/json'
2822 |                             }
2823 |                         });
2824 | 
2825 |                         // Erfolg loggen
2826 |                         if (!isanonymousModeEnabled) {
2827 |                             logEvent('server', 'swmsg', l.prefix_delete_all_chatsSuccess, t.deleteChatsSuccess, 'info');
2828 |                         }
2829 | 
2830 |                         return {
2831 |                             data: {},
2832 |                             message: response.data?.message || 'success',
2833 |                             status: response.status || 200
2834 |                         };
2835 |                     } catch (error) {
2836 |                         const deleteChatsErrorMessage = error.message || error.response?.data;
2837 |                         
2838 |                         // Fehler loggen
2839 |                         if (!isanonymousModeEnabled) {
2840 |                             logEvent('server', 'swmsg', l.prefix_delete_all_chatsError, 
2841 |                                      t.deleteChatsError.replace('${error}', deleteChatsErrorMessage), 'error');
2842 |                         }
2843 | 
2844 |                         return {
2845 |                             status: error.response?.status || 'E23-M-2300',
2846 |                             message: error.response?.data?.message || 'Error deleting all chat history.'
2847 |                         };
2848 |                     }
2849 |                 }
2850 |                 /* 2.4 Delete Specific Chat ##############################################################################*/
2851 |                 case 'delete_chat': {
2852 |                     const disabledResponse = checkToolEnabled('delete_chat');
2853 |                     if (disabledResponse) return disabledResponse;
2854 |                     
2855 |                     const { token } = message; // Token direkt aus `message` extrahieren
2856 |                     const tokenValidation = validateToken(token);
2857 |                     if (tokenValidation) return tokenValidation;
2858 |                     
2859 | 					const args = message.arguments || {}; // Argumente aus `message` extrahieren
2860 | 					const { chatId } = args; // chatId aus den Argumenten extrahieren
2861 | 
2862 |                     if (!chatId) {
2863 |                         return { status: 'E24-M-2400', message: t.missingChatId };
2864 |                     }
2865 | 
2866 |                     try {
2867 |                         const response = await this.axiosInstance.delete(`/chats/${chatId}`, {
2868 |                             headers: { 
2869 |                                 Authorization: `Bearer ${token}`,
2870 |                                 Accept: 'application/json'
2871 |                             }
2872 |                         });
2873 | 
2874 |                         // Erfolg loggen
2875 |                         if (!isanonymousModeEnabled) {
2876 |                             logEvent('server', 'swmsg', l.prefix_delete_chatSuccess, t.chatDeleted.replace('${chatId}', chatId), 'info');
2877 |                         }
2878 | 
2879 |                         return {
2880 |                             data: {},
2881 |                             message: response.data?.message || 'success',
2882 |                             status: response.status || 200
2883 |                         };
2884 |                     } catch (error) {
2885 |                         const deleteChatErrorMessage = error.message || error.response?.data;
2886 |                         
2887 |                         // Fehler loggen
2888 |                         if (!isanonymousModeEnabled) {
2889 |                             logEvent('server', 'swmsg', l.prefix_delete_chatError, 
2890 |                                      t.deleteChatError.replace('${chatId}', chatId).replace('${error}', deleteChatErrorMessage), 'error');
2891 |                         }
2892 | 
2893 |                         return {
2894 |                             status: error.response?.status || 'E24-M-2401',
2895 |                             message: error.response?.data?.message || `Error deleting chat with ID ${chatId}.`
2896 |                         };
2897 |                     }
2898 |                 }
2899 | 				/* 3.0 Create Source ##############################################################################*/
2900 | 				case 'create_source': {
2901 | 					const disabledResponse = checkToolEnabled('create_source');
2902 | 					if (disabledResponse) return disabledResponse;
2903 | 
2904 | 					const args = getArguments(message);
2905 | 					const token = message.token;
2906 | 
2907 | 					// Validierung: Erforderliche Parameter prüfen
2908 | 					if (!token) {
2909 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_create_source, t.missingTokenError, 'error');
2910 | 						return { status: 'E30-M-3050', message: t.missingTokenError };
2911 | 					}
2912 | 					if (!args || !args.name || !args.content) {
2913 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_create_source, t.missingNameAndContent, 'error');
2914 | 						return { status: 'E30-M-3051', message: t.missingParametersError.replace('${parameters}', 'name und content') };
2915 | 					}
2916 | 
2917 | 					const { name, content, groups } = args;
2918 | 
2919 | 					try {
2920 | 						// Gruppenvalidierung vorab durchführen
2921 | 						if (groups && groups.length > 0) {
2922 | 							const groupValidation = await this.validateGroups(groups, token, 'client', 'swmsg');
2923 | 							if (!groupValidation.isValid) {
2924 | 								if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_create_sourceInvalidGroups, t.InvalidGroups.replace('${GROUPS}', groupValidation.invalidGroups.join(', ')), 'error');
2925 | 								return {
2926 | 									status: 'E30-M-3052',
2927 | 									message: t.invalidGroupsError.replace('${invalidGroups}', groupValidation.invalidGroups.join(', '))
2928 | 								};
2929 | 							}
2930 | 						}
2931 | 
2932 | 						// API-Aufruf zur Erstellung der Quelle
2933 | 						const createSourceResponse = await this.axiosInstance.post(
2934 | 							'/sources',
2935 | 							{ name, content, groups },
2936 | 							{ headers: { Authorization: `Bearer ${token}` } }
2937 | 						);
2938 | 
2939 | 						// Loggen der erfolgreichen Erstellung der Quelle
2940 | 						if (!isanonymousModeEnabled) {
2941 | 							logEvent(
2942 | 								'client',
2943 | 								'message',
2944 | 								l.prefix_create_sourceSuccess,
2945 | 								t.createSourceSuccess.replace('${data}', JSON.stringify(createSourceResponse.data)),
2946 | 								'info'
2947 | 							);
2948 | 						}
2949 | 
2950 | 						// Erfolgsantwort
2951 | 						return {
2952 | 							status: createSourceResponse.data?.status || 'ok',
2953 | 							message: createSourceResponse.data?.message || 'Quelle erfolgreich erstellt.',
2954 | 							data: createSourceResponse.data?.data,
2955 | 						};
2956 | 					} catch (error) {
2957 | 						const createSourceError = error.message || JSON.stringify(error.response?.data);
2958 | 						// Loggen des Fehlers bei der Erstellung der Quelle
2959 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_create_sourceError, t.createSourceError.replace('${error}', createSourceError), 'error');
2960 | 
2961 | 						// Fehlerhafte Antwort
2962 | 						if (error.response) {
2963 | 							return {
2964 | 								status: 'E30-M-3053',
2965 | 								message: error.response?.data?.message || error.message || t.noErrorMessage,
2966 | 								details: {
2967 | 									status: error.response.status,
2968 | 									headers: error.response.headers,
2969 | 									data: error.response.data,
2970 | 								},
2971 | 							};
2972 | 						} else if (error.request) {
2973 | 							return {
2974 | 								status: 'E30-M-3054',
2975 | 								message: t.noServerResponse,
2976 | 								details: { request: error.request },
2977 | 							};
2978 | 						} else {
2979 | 							return {
2980 | 								status: 'E30-M-3055',
2981 | 								message: error.message || t.unknownError,
2982 | 							};
2983 | 						}
2984 | 					}
2985 | 				}
2986 | 				/* 3.1 Get Source #################################################################################*/
2987 | 				case 'get_source': {
2988 | 					const disabledResponse = checkToolEnabled('get_source');
2989 | 					if (disabledResponse) return disabledResponse;
2990 | 					const { token, arguments: args } = message; // Extrahiere den Token und die Argumente
2991 | 					const { sourceId } = args; // Extrahiere sourceId aus den Argumenten
2992 | 
2993 | 					if (!sourceId) {
2994 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_source, t.sourceIdRequiredRetrieveSource, 'error');
2995 | 						return { status: 'E31-M-3150', message: t.sourceIdRequiredRetrieveSource };
2996 | 					}
2997 | 
2998 | 					// Loggen des Beginns der Quellenanfrage
2999 | 					if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_source, t.makingGetSourceRequest.replace('${sourceId}', sourceId), 'info');
3000 | 
3001 | 					try {
3002 | 						const sourceResponse = await this.axiosInstance.get(`/sources/${sourceId}`, {
3003 | 							headers: {
3004 | 								Authorization: `Bearer ${token}`, // Nutze den vom Client bereitgestellten Token
3005 | 							},
3006 | 						});
3007 | 
3008 | 						// Loggen der erhaltenen Quellenantwort
3009 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_sourceSuccess, t.gotGetSourceResponse.replace('${data}', JSON.stringify(sourceResponse.data, null, 2)), 'info');
3010 | 
3011 | 						return {
3012 | 							content: sourceResponse.data,
3013 | 						};
3014 | 					} catch (error) {
3015 | 						// Loggen des Fehlers bei der Quellenanfrage
3016 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_get_sourceError, t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error.response?.data, null, 2)), 'error');
3017 | 						return {
3018 | 							status: 'E31-M-3151',
3019 | 							message: t.apiErrorDetails
3020 | 								.replace('${status}', error.response?.status || 'E31-M-3151')
3021 | 								.replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)),
3022 | 						};
3023 | 					}
3024 | 				}
3025 | 				/* 3.2 List Sources ###############################################################################*/
3026 | 				case 'list_sources': {
3027 | 					const disabledResponse = checkToolEnabled('list_sources');
3028 | 					if (disabledResponse) return disabledResponse;
3029 | 					const { token, attributes } = message; // Extrahiere den Token und die Attribute
3030 | 
3031 | 					if (!attributes || !attributes.groupName) {
3032 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_sources, t.groupNameRequired, 'error');
3033 | 						return { status: 'E32-M-3250', message: t.groupNameRequired };
3034 | 					}
3035 | 
3036 | 					const groupName = attributes.groupName; // Extrahiere den groupName aus attributes
3037 | 
3038 | 					// Loggen des Beginns der Quellenliste-Anfrage
3039 | 					if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_sources, t.fetchingSources.replace('${groupName}', groupName), 'info');
3040 | 
3041 | 					try {
3042 | 						// Führe die API-Anfrage aus, um die Quellen für die Gruppe zu erhalten
3043 | 						const sourceResponse = await this.axiosInstance.post(
3044 | 							'/sources/groups',
3045 | 							{ groupName },
3046 | 							{
3047 | 								headers: {
3048 | 									Authorization: `Bearer ${token}`, // Nutze den vom Client bereitgestellten Token
3049 | 								},
3050 | 							}
3051 | 						);
3052 | 
3053 | 						// Loggen der erhaltenen Quellenliste
3054 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_sourcesSuccess, t.sourcesRetrieved.replace('${data}', JSON.stringify(sourceResponse.data, null, 2)), 'info');
3055 | 
3056 | 						return {
3057 | 							content: sourceResponse.data, // Sende die Antwort zurück
3058 | 						};
3059 | 					} catch (error) {
3060 | 						// Loggen des Fehlers bei der Quellenliste-Anfrage
3061 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_sourcesError, t.groupValidationError.replace('${error}', error.message || JSON.stringify(error.response?.data)), 'error');
3062 | 						return {
3063 | 							status: 'E32-M-3251',
3064 | 							message: error.response?.data?.message || error.message || t.noErrorMessage,
3065 | 						};
3066 | 					}
3067 | 				}
3068 | 				/* 3.3 Edit Source ################################################################################*/
3069 | 				case 'edit_source': {
3070 | 					const disabledResponse = checkToolEnabled('edit_source');
3071 | 					if (disabledResponse) return disabledResponse;
3072 | 
3073 | 					const { token, arguments: args } = message;
3074 | 					const { sourceId, title, content, groups } = args;
3075 | 
3076 | 					// Validierung: Erforderliche Parameter
3077 | 					if (!sourceId) {
3078 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_source, t.sourceIdRequiredEditSource, 'error');
3079 | 						return {
3080 | 							status: 'E33-M-3350',
3081 | 							message: t.missingParameterError.replace('${parameter}', 'sourceId'),
3082 | 						};
3083 | 					}
3084 | 
3085 | 					// Loggen des Beginns der Quellenbearbeitung
3086 | 					if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_source, t.editSourceLog.replace('${sourceId}', sourceId).replace('${title}', title || 'unverändert'), 'info');
3087 | 
3088 | 					try {
3089 | 						// Nur Felder senden, die tatsächlich aktualisiert werden sollen
3090 | 						const payload = {};
3091 | 						if (title) payload.title = title;
3092 | 						if (content) payload.content = content;
3093 | 						if (groups) payload.groups = groups;
3094 | 
3095 | 						const editSourceResponse = await this.axiosInstance.patch(
3096 | 							`/sources/${sourceId}`,
3097 | 							payload,
3098 | 							{
3099 | 								headers: {
3100 | 									Authorization: `Bearer ${token}` // Nutze den bereitgestellten Token
3101 | 								},
3102 | 							}
3103 | 						);
3104 | 
3105 | 						// Loggen der erfolgreichen Quellenbearbeitung
3106 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_sourceSuccess, t.editSourceSuccess.replace('${data}', JSON.stringify(editSourceResponse.data, null, 2)), 'info');
3107 | 
3108 | 						// Erfolgreiche Antwort
3109 | 						return {
3110 | 							status: editSourceResponse.data?.status || 'ok',
3111 | 							message: editSourceResponse.data?.message || 'Quelle erfolgreich bearbeitet.',
3112 | 							data: editSourceResponse.data?.data
3113 | 						};
3114 | 					} catch (error) {
3115 | 						const editSourceError = error.message || JSON.stringify(error.response?.data);
3116 | 						// Loggen des Fehlers bei der Quellenbearbeitung
3117 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_sourceError, t.editSourceError.replace('${error}', editSourceError), 'error');
3118 | 
3119 | 						// Fehlerhafte Antwort
3120 | 						return {
3121 | 							data: {},
3122 | 							message: error.response?.data?.message || 'Bearbeiten der Quelle fehlgeschlagen. Bitte versuchen Sie es später erneut.',
3123 | 							status: error.response?.status || 'E33-M-3351', // Internal Server Error
3124 | 						};
3125 | 					}
3126 | 				}
3127 | 				/* 3.4 Delete Source ##############################################################################*/
3128 | 				case 'delete_source': {
3129 | 					const disabledResponse = checkToolEnabled('delete_source');
3130 | 					if (disabledResponse) return disabledResponse;
3131 | 					const { token, arguments: args } = message;
3132 | 					const { sourceId } = args;
3133 | 
3134 | 					if (!sourceId) {
3135 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_source, t.sourceIdRequiredDeleteSource, 'error');
3136 | 						return { status: 'E34-M-3450', message: t.groupNameRequired.replace('${param}', 'sourceId') };
3137 | 					}
3138 | 
3139 | 					// Loggen des Beginns der Quellenlöschung
3140 | 					if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_source, t.deletesourceLog.replace('${SourceName}', sourceId), 'info');
3141 | 
3142 | 					try {
3143 | 						const deleteResponse = await this.axiosInstance.delete(`/sources/${sourceId}`, {
3144 | 							headers: { Authorization: `Bearer ${token}` },
3145 | 						});
3146 | 
3147 | 						// Loggen der erfolgreichen Quellenlöschung
3148 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_sourceSuccess, t.deleteUserSuccess.replace('${data}', JSON.stringify(deleteResponse.data, null, 2)), 'info');
3149 | 
3150 | 						return {
3151 | 							content: deleteResponse.data,
3152 | 						};
3153 | 					} catch (error) {
3154 | 						const deleteSourceError = error.message || JSON.stringify(error.response?.data);
3155 | 						// Loggen des Fehlers bei der Quellenbearbeitung
3156 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_sourceError, t.deleteSourceError.replace('${error}', deleteSourceError), 'error');
3157 | 
3158 | 						return {
3159 | 							data: {},
3160 | 							message: error.response?.data?.message || 'Löschen der Quelle fehlgeschlagen. Bitte versuchen Sie es später erneut.',
3161 | 							status: error.response?.status || 'E34-M-3451', // Internal Server Error
3162 | 						};
3163 | 					}
3164 | 				}				
3165 | 				/* 4.0 List Groups ################################################################################*/
3166 | 				case 'list_groups': {
3167 | 					const disabledResponse = checkToolEnabled('list_groups');
3168 | 					if (disabledResponse) return disabledResponse;
3169 | 
3170 | 					const { token } = message; // Token direkt extrahieren
3171 | 
3172 | 					try {
3173 | 						await this.ensureAuthenticated(token);
3174 | 
3175 | 						const response = await this.axiosInstance.get('/groups');
3176 | 						let assignableGroups = response.data?.data?.assignableGroups || [];
3177 | 						const personalGroups = response.data?.data?.personalGroups || [];
3178 | 						const messageText = response.data?.message || 'no_message'; // Fallback für Nachricht
3179 | 						const status = response.data?.status || 'E40-M-4050'; // Fallback für Status
3180 | 
3181 | 						if (isRestrictedGroupsEnabled) {
3182 | 							// Loggen der Einschränkung bei RESTRICTED_GROUPS
3183 | 							if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_groupsWarning, t.restrictedGroupsWarning, 'warn');
3184 | 							assignableGroups = ["NO ACCESS ALLOWED BY THE MCP-SERVER CONFIG"]; // Alle assignableGroups entfernen
3185 | 						}
3186 | 
3187 | 						// Loggen der erfolgreichen Gruppenliste
3188 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_groupsSuccess, t.listGroupsSuccess.replace('${GROUPS}', JSON.stringify(response.data)), 'info');
3189 | 						// )`Gruppenliste abgerufen: ${JSON.stringify(response.data)}`, 'info');
3190 | 
3191 | 						return {
3192 | 							data: {
3193 | 								personalGroups,
3194 | 								assignableGroups,
3195 | 								message: messageText,
3196 | 								status,
3197 | 							},
3198 | 						};
3199 | 					} catch (error) {
3200 | 						const fetchGroupsError = error.message || JSON.stringify(error.response?.data);
3201 | 						// Loggen des Fehlers beim Abrufen der Gruppen
3202 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_list_groupsError, t.fetchGroupsError.replace('${error}', fetchGroupsError), 'error');
3203 | 
3204 | 						// Detaillierte Fehlerbehandlung
3205 | 						if (axios.isAxiosError(error)) {
3206 | 							const status = error.response?.status;
3207 | 							const serverMessage = error.response?.data?.message || error.message || 'no error message';
3208 | 							return {
3209 | 								status: 'E40-M-4051',
3210 | 								message: `${t.fetchGroupsErrorPrefix}: ${serverMessage} (Status: ${status})`,
3211 | 								// message: t.fetchGroupsErrorPrefix: ${serverMessage} (Status: ${status}),
3212 | 							};
3213 | 						}
3214 | 
3215 | 						return {
3216 | 							status: 'E40-M-4052',
3217 | 							message: t.unknownErrorOccured,
3218 | 						};
3219 | 					}
3220 | 				}
3221 | 				/* 4.1 Store Group ################################################################################*/
3222 | 				case 'store_group': {
3223 | 					const disabledResponse = checkToolEnabled('store_group');
3224 | 					if (disabledResponse) return disabledResponse;
3225 | 
3226 | 					const { groupName, description } = message.arguments; // Extrahiere die Argumente
3227 | 					const clientToken = message.token; // Token aus der Anfrage
3228 | 
3229 | 					if (!groupName || !description) {
3230 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_group, t.missingGroupNameAndDesc, 'error');
3231 | 						return { 
3232 | 						  status: 'E41-M-4150', 
3233 | 						  message: t.missingGroupNameAndDesc 
3234 | 						};
3235 | 					}
3236 | 
3237 | 					if (!clientToken) {
3238 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_group, t.missingTokenError, 'error');
3239 | 						return { status: 'E41-M-4151', message: t.missingTokenError };
3240 | 					}
3241 | 
3242 | 					try {
3243 | 						// API-Aufruf mit dem vom Client bereitgestellten Token
3244 | 						const createGroupResponse = await this.axiosInstance.post(
3245 | 							'/groups',
3246 | 							{ groupName, description },
3247 | 							{
3248 | 								headers: {
3249 | 									Authorization: `Bearer ${clientToken}` // Nutze nur den Client-Token
3250 | 								}
3251 | 							}
3252 | 						);
3253 | 
3254 | 						// Loggen der erfolgreichen Gruppenerstellung
3255 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_groupSuccess, t.createGroupSuccess.replace('${data}', JSON.stringify(createGroupResponse.data)), 'info');
3256 | 
3257 | 						return {
3258 | 							content: createGroupResponse.data,
3259 | 						};
3260 | 					} catch (error) {
3261 | 						const apiError = error.response?.data?.message || error.message || t.noErrorMessage;
3262 | 
3263 | 						if (!isanonymousModeEnabled) {
3264 | 							logEvent('client', 'swmsg', l.prefix_store_groupError, t.apiRequestError.replace('${error}', apiError), 'error');
3265 | 						}
3266 | 
3267 | 						return {
3268 | 							status: 'E41-M-4152',
3269 | 							message: error.response?.data?.message || error.message || t.noErrorMessage,
3270 | 						};
3271 | 					}
3272 | 				}
3273 | 				/* 4.2 Delete Group ###################################################################################*/
3274 | 				case 'delete_group': {
3275 | 					const disabledResponse = checkToolEnabled('delete_group');
3276 | 					if (disabledResponse) return disabledResponse;
3277 | 
3278 | 					const { token, arguments: args } = message; // Extrahiere Token und Argumente
3279 | 					const { groupName } = args;
3280 | 
3281 | 					if (!groupName) {
3282 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_group, t.missingGroupNameParam, 'error');
3283 | 						return { 
3284 | 						  status: 'E42-M-4250', 
3285 | 						  message: t.missingGroupNameParam 
3286 | 						};
3287 | 					}
3288 | 
3289 | 					// Loggen des Beginns der Gruppenlöschung
3290 | 					if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_group, t.deleteGroupLog.replace('${groupName}', groupName), 'info');
3291 | 
3292 | 					try {
3293 | 						// API-Aufruf mit dem Token des Clients
3294 | 						const deleteGroupResponse = await this.axiosInstance.delete('/groups', {
3295 | 							data: { groupName }, // JSON-Body für DELETE-Request
3296 | 							headers: {
3297 | 								Authorization: `Bearer ${token}` // Nutze den vom Client bereitgestellten Token
3298 | 							},
3299 | 						});
3300 | 
3301 | 						// Loggen der erfolgreichen Gruppenlöschung
3302 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_groupSuccess, t.deleteGroupSuccessLog.replace('${data}', JSON.stringify(deleteGroupResponse.data)), 'info');
3303 | 
3304 | 						return {
3305 | 							data: deleteGroupResponse.data?.data || {},
3306 | 							message: deleteGroupResponse.data?.message || 'success',
3307 | 							status: deleteGroupResponse.status || 200,
3308 | 						};
3309 | 					} catch (error) {
3310 | 						const deleteSourceError = error.response?.data || error.message;
3311 | 						// Loggen des Fehlers bei der Gruppenlöschung
3312 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_groupError, t.deleteSourceError.replace('${error}', deleteSourceError), 'error');
3313 | 
3314 | 						return {
3315 | 							status: 'E42-M-4251',
3316 | 							message: error.response?.data?.message || error.message || t.noErrorMessage,
3317 | 						};
3318 | 					}
3319 | 				}
3320 | 				/* 5.0 Store User #################################################################################*/
3321 | 				case 'store_user': {
3322 | 					const disabledResponse = checkToolEnabled('store_user');
3323 | 					if (disabledResponse) return disabledResponse;
3324 | 					const { token, arguments: args } = message;
3325 | 
3326 | 					// Validierung der erforderlichen Parameter
3327 | 					if (!args || !args.name || !args.email || !args.password) {
3328 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_user, t.missingNameEmailPwd, 'error');
3329 | 						return { status: 'E50-M-5050', message: t.missingNameEmailPwd };
3330 | 					}
3331 | 
3332 | 					const Pwd = args.password;
3333 | 
3334 | 					// Überprüfe, ob das Passwort vorhanden ist
3335 | 					if (!Pwd) {
3336 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_user, t.passwordIsRequired, 'error');
3337 | 						return {
3338 | 							status: 'E10-M-1050',
3339 | 							message: t.passwordIsRequired
3340 | 						};
3341 | 					}
3342 | 
3343 | 					let password;
3344 | 
3345 | 					// Passwort entschlüsseln, falls erforderlich
3346 | 					if (typeof PwEncryption !== 'undefined' && PwEncryption) {
3347 | 						password = decryptPassword(Pwd);
3348 | 					} else {
3349 | 						password = Pwd;
3350 | 					}
3351 | 
3352 | 					try {
3353 | 						// Payload für die API-Anfrage
3354 | 						const payload = {
3355 | 							name: args.name,
3356 | 							email: args.email,
3357 | 							language: args.language || 'en',
3358 | 							timezone: args.timezone || 'Europe/Berlin',
3359 | 							password: password,
3360 | 							usePublic: args.usePublic || false,
3361 | 							groups: args.groups || [],
3362 | 							roles: args.roles || [],
3363 | 							activateFtp: args.activateFtp || false,
3364 | 							ftpPassword: args.ftpPassword || '',
3365 | 						};
3366 | 
3367 | 						// Loggen des Payloads vor der API-Anfrage
3368 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_user, t.createUserLog.replace('${payload}', JSON.stringify(payload)), 'info');
3369 | 
3370 | 						// API-Aufruf
3371 | 						const createUserResponse = await this.axiosInstance.post('/users', payload, {
3372 | 							headers: {
3373 | 								Authorization: `Bearer ${token}`
3374 | 							}
3375 | 						});
3376 | 
3377 | 						// Loggen der erfolgreichen Benutzererstellung
3378 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_userSuccess, t.createUserSuccess.replace('${data}', JSON.stringify(createUserResponse.data)), 'info');
3379 | 
3380 | 						return {
3381 | 							content: createUserResponse.data,
3382 | 						};
3383 | 					} catch (error) {
3384 | 						const createUserError = error.message || JSON.stringify(error.response?.data);
3385 | 						// Loggen des Fehlers bei der Quellenbearbeitung
3386 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_store_userError, t.createUserError.replace('${error}', createUserError), 'error');
3387 | 						// Fehlerhafte Antwort
3388 | 						return {
3389 | 							data: {},
3390 | 							message: error.response?.data?.message || 'Fehler beim Anlegen des Benutzers.',
3391 | 							status: error.response?.status || 'E50-M-5051', // Internal Server Error
3392 | 						};
3393 | 					}
3394 | 				}
3395 | 				/* 5.1 Edit User ##################################################################################*/
3396 | 				case 'edit_user': {
3397 | 					const disabledResponse = checkToolEnabled('edit_user');
3398 | 					if (disabledResponse) return disabledResponse;
3399 | 
3400 | 					const { token, arguments: args } = message;
3401 | 					const tokenValidation = validateToken(token);
3402 | 					if (tokenValidation) return tokenValidation;
3403 | 
3404 | 					// Mindestens die E-Mail muss angegeben sein, um den User zu identifizieren
3405 | 					if (!args || !args.email) {
3406 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_user, t.emailRequiredForEdit, 'error');
3407 | 						return {
3408 | 							status: 'E51-M-5100',
3409 | 							message: t.emailRequiredForEdit
3410 | 						};
3411 | 					}
3412 | 					let password = null;
3413 | 
3414 | 					if (args.password) {
3415 | 						const Pwd = args.password;
3416 | 						if (!Pwd) {
3417 | 							if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_user, t.passwordIsRequired, 'error');
3418 | 							return {
3419 | 								status: 'E51-M-1050',
3420 | 								message: t.passwordIsRequired,
3421 | 							};
3422 | 						}
3423 | 						if (typeof PwEncryption !== 'undefined' && PwEncryption) {
3424 | 							password = decryptPassword(Pwd);
3425 | 						} else {
3426 | 							password = Pwd;
3427 | 						}
3428 | 					}
3429 | 
3430 | 					try {
3431 | 						// Nur Felder senden, die tatsächlich aktualisiert werden sollen
3432 | 						const payload = {};
3433 | 						if (args.name) payload.name = args.name;
3434 | 						if (args.password) payload.password = password;
3435 | 						if (args.language) payload.language = args.language;
3436 | 						if (args.timezone) payload.timezone = args.timezone;
3437 | 						if (Array.isArray(args.roles)) payload.roles = args.roles;
3438 | 						if (Array.isArray(args.groups)) payload.groups = args.groups;
3439 | 						if (typeof args.usePublic === 'boolean') payload.usePublic = args.usePublic;
3440 | 
3441 | 						// E-Mail ist Pflicht, um den Benutzer auf dem Server zu finden
3442 | 						payload.email = args.email;
3443 | 						const response = await this.axiosInstance.patch(
3444 | 							'/users',
3445 | 							payload,
3446 | 							{
3447 | 								headers: { Authorization: `Bearer ${token}` }
3448 | 							}
3449 | 						);
3450 | 
3451 | 						// Loggen der erfolgreichen Benutzerbearbeitung
3452 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_userSuccess, t.editUserSuccess.replace('${data}', JSON.stringify(response.data)), 'info');
3453 | 
3454 | 						return {
3455 | 							status: response.data?.status || 'ok',
3456 | 							message: response.data?.message || 'Benutzer erfolgreich bearbeitet.',
3457 | 							data: response.data?.data
3458 | 						};
3459 | 					} catch (error) {
3460 | 						const editUserError = error.message || JSON.stringify(error.response?.data);
3461 | 						// Loggen des Fehlers bei der Quellenbearbeitung
3462 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_edit_userError, t.editUserError.replace('${error}', editUserError), 'error');
3463 | 						// Fehlerhafte Antwort
3464 | 						return {
3465 | 							data: {},
3466 | 							message: error.response?.data?.message || t.editUserError.replace('${error}', editUserError),
3467 | 							status: error.response?.status || 'E51-M-5151', // Internal Server Error
3468 | 						};
3469 | 					}
3470 | 				}
3471 | 				/* 5.2 Delete User ################################################################################*/
3472 | 				case 'delete_user': {
3473 | 					const disabledResponse = checkToolEnabled('delete_user');
3474 | 					if (disabledResponse) return disabledResponse;
3475 | 					const { token, arguments: args } = message;
3476 | 
3477 | 					const { email } = args;
3478 | 
3479 | 					if (!email) {
3480 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_user, t.emailRequiredForDelete, 'error');
3481 | 						return { status: 'E52-M-5250', message: t.emailRequiredForDelete };
3482 | 					}
3483 | 
3484 | 					// Loggen des Beginns der Benutzerlöschung
3485 | 					if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_user, t.deleteUserLog.replace('${UserName}', email), 'info');
3486 | 
3487 | 					try {
3488 | 						const response = await this.axiosInstance.delete(
3489 | 							'/users',
3490 | 							{
3491 | 								data: { email },
3492 | 								headers: { Authorization: `Bearer ${token}` },
3493 | 							}
3494 | 						);
3495 | 
3496 | 						// Loggen der erfolgreichen Benutzerlöschung
3497 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_userSuccess, t.deleteUserSuccess.replace('${data}', JSON.stringify(response.data, null, 2)), 'info');
3498 | 
3499 | 						return {
3500 | 							content: response.data,
3501 | 						};
3502 | 					} catch (error) {
3503 | 						const deleteUserError = error.message || JSON.stringify(error.response?.data);
3504 | 						// Loggen des Fehlers bei der Quellenbearbeitung
3505 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_delete_userError, t.deleteUserError.replace('${error}', deleteUserError), 'error');
3506 | 						// Fehlerhafte Antwort
3507 | 						return {
3508 | 							data: {},
3509 | 							message: error.response?.data?.message || 'Löschen des Users fehlgeschlagen. Bitte versuchen Sie es später erneut.',
3510 | 							status: error.response?.status || 'E52-M-5251', // Internal Server Error
3511 | 						};
3512 | 					}
3513 | 				}
3514 |                 /* 5.3 Reactivate User ################################################################################*/
3515 |                 case 'reactivate_user': {
3516 |                     const disabledResponse = checkToolEnabled('reactivate_user');
3517 |                     if (disabledResponse) return disabledResponse;
3518 |                     const { token, arguments: args } = message;
3519 | 
3520 |                     const { email } = args;
3521 | 
3522 |                     if (!email) {
3523 |                         if (!isanonymousModeEnabled) {
3524 |                             logEvent('client', 'swmsg', l.prefix_reactivate_user, t.emailRequiredForReactivate, 'error');
3525 |                         }
3526 |                         return { status: 'E53-M-5300', message: t.emailRequiredForReactivate };
3527 |                     }
3528 | 
3529 |                     // Loggen des Beginns der Benutzerreaktivierung
3530 |                     if (!isanonymousModeEnabled) {
3531 |                         logEvent('client', 'swmsg', l.prefix_reactivate_user, t.reactivateUserLog.replace('${UserName}', email), 'info');
3532 |                     }
3533 | 
3534 |                     try {
3535 |                         const response = await this.axiosInstance.post(
3536 |                             '/api/v1/users/reactivate',
3537 |                             { email },
3538 |                             {
3539 |                                 headers: { 
3540 |                                     Authorization: `Bearer ${token}`,
3541 |                                     Accept: 'application/json'
3542 |                                 }
3543 |                             }
3544 |                         );
3545 | 
3546 |                         // Loggen der erfolgreichen Benutzerreaktivierung
3547 |                         if (!isanonymousModeEnabled) {
3548 |                             logEvent('client', 'swmsg', l.prefix_reactivate_userSuccess, 
3549 |                                      t.reactivateUserSuccess.replace('${data}', JSON.stringify(response.data, null, 2)), 'info');
3550 |                         }
3551 | 
3552 |                         return {
3553 |                             content: response.data,
3554 |                         };
3555 |                     } catch (error) {
3556 |                         const reactivateUserError = error.message || JSON.stringify(error.response?.data);
3557 |                         // Loggen des Fehlers bei der Benutzerreaktivierung
3558 |                         if (!isanonymousModeEnabled) {
3559 |                             logEvent('client', 'swmsg', l.prefix_reactivate_userError, 
3560 |                                      t.reactivateUserError.replace('${error}', reactivateUserError), 'error');
3561 |                         }
3562 |                         // Fehlerhafte Antwort
3563 |                         return {
3564 |                             data: {},
3565 |                             message: error.response?.data?.message || 'Reaktivierung des Benutzers fehlgeschlagen. Bitte versuchen Sie es später erneut.',
3566 |                             status: error.response?.status || 'E53-M-5301', // Internal Server Error
3567 |                         };
3568 |                     }
3569 |                 }
3570 | 				/* 6.0 Open AI compatible API Chat #######################################################################################*/
3571 |                 case 'oai_comp_api_chat': {
3572 |                     const disabledResponse = checkToolEnabled('oai_comp_api');
3573 |                     if (disabledResponse) return disabledResponse;
3574 | 
3575 |                     const { token, arguments: args } = message;
3576 |                     if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chat, t.extractedToken.replace('${token}', token), 'info');
3577 | 
3578 |                     // Token prüfen und validieren
3579 |                     if (!token) {
3580 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatError, t.noTokenError, 'error');
3581 |                         return { status: 'E60-M-6000', message: t.missingTokenError };
3582 |                     }
3583 | 
3584 |                     // Argument-Validierung
3585 |                     if (!args || !args.question) {
3586 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatError, t.missingArgumentsError.replace('${args}', JSON.stringify(args)), 'error');
3587 |                         return {
3588 |                             status: 'error',
3589 |                             message: t.missingArgumentsError.replace('${args}', JSON.stringify(args)),
3590 |                         };
3591 |                     }
3592 | 
3593 |                     const { question, usePublic, groups, language } = args;
3594 | 
3595 | 					// Konflikt zwischen `usePublic` und `groups` lösen
3596 | 					if (usePublic && groups && groups.length > 0) {
3597 | 						if (!isanonymousModeEnabled) logEvent('system', 'swmsg', l.prefix_chatWarning, t.publicGroupsConflictWarning, 'warn');
3598 | 						args.usePublic = false;
3599 | 					}
3600 | 
3601 | 					try {
3602 | 						// Loggen der Chat-Anfrage
3603 | 						if (!isanonymousModeEnabled) logEvent('server', 'oamsg', l.prefix_chatRequest, t.sendingChatRequest
3604 | 							.replace('${question}', question)
3605 | 							.replace('${usePublic}', usePublic)
3606 | 							.replace('${groups}', JSON.stringify(groups))
3607 | 							.replace('${language}', language), 'info');
3608 | 
3609 |                         const response = await this.axiosInstance.post(
3610 |                             '/chats',
3611 |                             {
3612 |                                 question,
3613 |                                 usePublic: usePublic || false,
3614 |                                 groups: Array.isArray(groups) ? groups : [groups],
3615 |                                 language: language || 'de',
3616 |                             },
3617 |                             { headers: { Authorization: `Bearer ${token}` } }
3618 |                         );
3619 | 
3620 |                         const data = response.data?.data || {};
3621 |                         // Loggen der erfolgreichen Chat-Antwort
3622 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatSuccess, t.chatResponseSuccess.replace('${data}', JSON.stringify(data)), 'info');
3623 | 
3624 |                         // Erfolgsantwort mit Status und Daten
3625 |                         return {
3626 |                             status: response.data?.status || 'ok',
3627 |                             message: response.data?.message || 'Chat erfolgreich.',
3628 |                             content: {
3629 |                                 chatId: data.chatId,
3630 |                                 answer: data.answer,
3631 |                                 sources: data.sources || [],
3632 |                             },
3633 |                         };
3634 |                     } catch (error) {
3635 |                         const chatApiErrorMessage = error.message || error.response?.data;
3636 |                         // Loggen des Fehlers bei der Chat-API-Anfrage
3637 |                         if (!isanonymousModeEnabled) logEvent('server', 'swmsg', l.prefix_chatApiError, t.chatApiError.replace('${error}', chatApiErrorMessage), 'error');
3638 | 
3639 |                         // Fehlerantwort mit Status und Nachricht
3640 |                         return {
3641 |                             status: error.response?.status || 'E60-M-6002',
3642 |                             message: error.response?.data?.message || t.chatApiErrorDefault,
3643 |                         };
3644 |                     }
3645 |                 }			
3646 | 				/* 6.1 Open AI compatible API Continue Chat ##############################################################################*/
3647 | 				case 'oai_comp_api_continue_chat': {
3648 | 					const disabledResponse = checkToolEnabled('oai_comp_api');
3649 | 					if (disabledResponse) return disabledResponse;
3650 | 
3651 | 					const token = message.token; // Token direkt extrahieren
3652 | 					const args = message.arguments || {}; // Sichere Extraktion der Argumente
3653 | 					const { chatId, question } = args;
3654 | 
3655 | 					if (!args || !args.chatId || !args.question) {
3656 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_continue_chat, t.missingChatParams, 'error');
3657 | 						return { status: 'E61-M-6150', message: t.missingChatParams };
3658 | 					}
3659 | 
3660 | 					try {
3661 | 						const continueChatResponse = await this.axiosInstance.patch(
3662 | 							`/chats/${chatId}`,
3663 | 							{ question },
3664 | 							{ headers: { Authorization: `Bearer ${token}` } }
3665 | 						);
3666 | 
3667 | 						// Loggen der erfolgreichen Continue-Chat-Antwort
3668 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_continue_chatSuccess, t.conversationSuccess.replace('${data}', JSON.stringify(continueChatResponse.data, null, 2)), 'info');
3669 | 
3670 | 						return {
3671 | 							content: {
3672 | 								chatId: continueChatResponse.data.data.chatId,
3673 | 								answer: continueChatResponse.data.data.answer,
3674 | 								sources: continueChatResponse.data.sources || [],
3675 | 								message: continueChatResponse.data.message,
3676 | 								status: continueChatResponse.data.status,
3677 | 							},
3678 | 						};
3679 | 					} catch (error) {
3680 | 						// Loggen des Fehlers bei der Continue-Chat-API-Anfrage
3681 | 						if (!isanonymousModeEnabled) logEvent('client', 'oamsg', l.prefix_apiRequestError, t.apiRequestError.replace('${error}', error.message), 'error');
3682 | 						return {
3683 | 							status: 'E61-M-6151',
3684 | 							message: error.response?.data?.message || error.message || t.noErrorMessage,
3685 | 						};
3686 | 					}
3687 | 				}
3688 | 				/* 9.0 Generate Key ###############################################################################*/
3689 | 				case 'keygen': {
3690 | 					const disabledResponse = checkToolEnabled('keygen');
3691 | 					if (disabledResponse) return disabledResponse;
3692 | 
3693 | 					const { password } = message.arguments;
3694 | 
3695 | 					try {
3696 | 						// Passwort verschlüsseln
3697 | 						const encryptedPassword = getEncryptedKey(password);
3698 | 
3699 | 						// Loggen der erfolgreichen Key-Generierung
3700 | 						if (!isanonymousModeEnabled) logEvent('client', 'swmsg', l.prefix_keygen, t.keygenSuccess, 'info');
3701 | 
3702 | 						// Schlüssel zurückgeben
3703 | 						return {
3704 | 							data: {
3705 | 								key: encryptedPassword
3706 | 							},
3707 | 							status: 'ok',
3708 | 							message: t.KeygenRequired,
3709 | 						};
3710 | 					} catch (error) {
3711 | 						// Loggen des Fehlers bei der Key-Generierung
3712 | 						if (!isanonymousModeEnabled) logEvent(
3713 | 							'client', 'message', l.prefix_keygenError,
3714 | 							t.keygenErrorPrefix + ' ' + error.message,
3715 | 							'error'
3716 | 						);
3717 | 						return {
3718 | 							data: {},
3719 | 							message: error.message || 'Keygen fehlgeschlagen.',
3720 | 							status: 'E90-M-1150',
3721 | 						};
3722 | 					}
3723 | 				}
3724 | 				default: {
3725 | 					// Loggen unbekannter Befehle
3726 | 					if (!isanonymousModeEnabled) logEvent(
3727 | 						'system', 'message', l.prefix_unknownCommand,
3728 | 						t.unknownCommandError.replace('${cmd}', message.command),
3729 | 						'warn'
3730 | 					)
3731 | 					return { status: 'E99-M-9950', message: t.unknownCommandError.replace('${cmd}', message.command) };
3732 | 				}
3733 |             }
3734 | 		} catch (err) {
3735 | 			// Loggen des Fehlers im Haupt-Handler
3736 | 			console.log('Error object:', err);
3737 | 			console.log('Error message:', err?.message);
3738 | 			if (!isanonymousModeEnabled) logEvent('system', 'message', l.prefix_tcpServerError, `${t.tcpServerError} ${err.message || JSON.stringify(err, null, 2)}`, 'error');
3739 | 			return { status: 'E52-M-5252', message: err.message || t.internalServerError };
3740 | 			}
3741 | 		});
3742 | 	}
3743 | }	
3744 | const server = new PrivateGPTServer();
3745 | 
3746 | // Log-Viewer Webserver konfigurieren
3747 | const app = express();
3748 | const httpServer = createHttpServer(app);
3749 | const io = new SocketIoServer(httpServer);
3750 | 
3751 | 
3752 | // const LOG_FILE_PATH = path.join(__dirname, '../logs/server.log'); // Pfad zu Ihrer Logdatei
3753 | 
3754 | // Statische Dateien bereitstellen (optional, falls eine HTML-Oberfläche benötigt wird)
3755 | app.use(express.static(path.join(__dirname, 'public')));
3756 | io.on('connection', (socket) => {
3757 |     if (isWrittenLogfileEnabled) {
3758 |         logEvent(
3759 |             'server',
3760 |             'websocket',
3761 |             l.prefix_clientConnected,
3762 |             messages[lang].clientConnected,
3763 |             'info'
3764 |         );
3765 |         sendLogContent(socket);
3766 |     } else {
3767 |         // Optional: Informieren Sie den Client, dass das Logfile nicht aktiviert ist
3768 |         socket.emit('logUpdate', messages[lang].socketEmitLogNotActivated);
3769 |     }
3770 | 
3771 |     socket.on('disconnect', () => {
3772 |         if (isWrittenLogfileEnabled) {
3773 |             logEvent(
3774 |                 'server',
3775 |                 'websocket',
3776 |                 l.prefix_clientDisconnected,
3777 |                 messages[lang].clientDisconnected,
3778 |                 'info'
3779 |             );
3780 |         }
3781 |     });
3782 | });
3783 | 
3784 | // Funktion, um den Loginhalt an einen Client zu senden
3785 | const sendLogContent = async (socket) => {
3786 |     try {
3787 |         // Überprüfen, ob die Log-Datei existiert
3788 |         await fs.promises.access(LOG_FILE_PATH, fs.constants.F_OK);
3789 |         let data = await fs.promises.readFile(LOG_FILE_PATH, 'utf8');
3790 |         data = stripAnsi(data); // nutzt jetzt den Import
3791 |         socket.emit('logUpdate', data);
3792 |     } catch (err) {
3793 |         if (!isanonymousModeEnabled) logEvent(
3794 |             'server',
3795 |             'filesystem',
3796 |             l.prefix_logReadError,
3797 |             messages[lang].logReadError.replace('${error}', err.message),
3798 |             'error'
3799 |         );
3800 |         socket.emit('logUpdate', messages[lang].socketEmitLogReadError);
3801 |     }
3802 | };
3803 | 
3804 | // Überwachung der Logdatei auf Änderungen, nur wenn Schreiben aktiviert ist
3805 | if (isWrittenLogfileEnabled) {
3806 |     chokidar.watch(LOG_FILE_PATH).on('change', async () => {
3807 |         try {
3808 |             const data = await fs.promises.readFile(LOG_FILE_PATH, 'utf8');
3809 |             io.sockets.emit('logUpdate', data);
3810 |         } catch (err) {
3811 |             if (!isanonymousModeEnabled) logEvent(
3812 |                 'server',
3813 |                 'filesystem',
3814 |                 l.prefix_logChangeError,
3815 |                 messages[lang].logChangeError.replace('${error}', err.message),
3816 |                 'error'
3817 |             );
3818 |         }
3819 |     });
3820 | }
3821 | 
3822 | // Überwachung der Logdatei auf Änderungen
3823 | /*chokidar.watch(LOG_FILE_PATH).on('change', async () => {
3824 |     try {
3825 |         const data = await fs.promises.readFile(LOG_FILE_PATH, 'utf8');
3826 |         io.sockets.emit('logUpdate', data);
3827 |     } catch (err) {
3828 |         if (!isanonymousModeEnabled) logEvent(
3829 |             'server',
3830 |             'filesystem',
3831 |             l.prefix_logChangeError,
3832 |             messages[lang].logChangeError.replace('${error}', err.message),
3833 |             'error'
3834 |         );
3835 |     }
3836 | });*/
3837 | 
3838 | // Log-Viewer HTTP-Server starten
3839 | const WEB_PORT = 3000;
3840 | httpServer.listen(WEB_PORT, () => {
3841 |     if (!isanonymousModeEnabled) logEvent(
3842 |         'server',
3843 |         'web',
3844 |         l.prefix_logViewerRunning,
3845 |         messages[lang].logViewerRunning.replace('${port}', WEB_PORT),
3846 |         'info'
3847 |     );
3848 | });
3849 | 
3850 | // Server läuft
3851 | server.run().catch(error => {
3852 |     if (!isanonymousModeEnabled) logEvent(
3853 |         'server',
3854 |         'N/A',
3855 |         l.prefix_serverError,
3856 |         messages[lang].serverError.replace('${error}', error.message),
3857 |         'error'
3858 |     );
3859 | });
3860 | 
3861 | // Anzeige des Start-Headers
3862 | displayStartHeader();
```
Page 19/20FirstPrevNextLast