#
tokens: 42610/50000 1/501 files (page 14/16)
lines: off (toggle) GitHub
raw markdown copy
This is page 14 of 16. Use http://codebase.md/fujitsu-ai/mcp-server-for-mas-developments?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
│   ├── 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

--------------------------------------------------------------------------------
/ver/index_np.js:
--------------------------------------------------------------------------------

```javascript
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ErrorCode, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import axios from 'axios';
import https from 'https';
import dotenv from 'dotenv';
import net from 'net';
import { fileURLToPath } from 'url';
import path from 'path';
import fs from 'fs';
import crypto from 'crypto';


dotenv.config({ path: './pgpt.env' }); // Geben Sie explizit den Pfad zur Datei an

const templates = {
    success: '✔️ ${action}: ${details}',
    error: '❌ ${action} Fehler: ${details}',
    warning: '⚠️ ${action}: ${details}',
    configStart: '🚀 ${action}: ${details}', 
    info: '📤 ${action}...',
};

const messages = {
    de: {
        apiErrorDetails:            templates.error.replace('${action}', 'API-Fehler').replace('${details}', 'Status: ${status}, Daten: ${data}'),
        apiUrlInvalid:              templates.error.replace('${action}', 'Ungültige API_URL').replace('${details}', ''),
        apiUrlValidated:            templates.success.replace('${action}', 'API_URL erfolgreich validiert').replace('${details}', '${url}'),
        apiUrlWarning:              templates.warning.replace('${action}', 'Warnung').replace('${details}', 'API_URL beginnt nicht mit "https://". Die URL wird angepasst.'),
        apiUrlWarningV1:            templates.warning.replace('${action}', 'Warnung').replace('${details}', 'API_URL endet nicht mit "/api/v1". Die URL wird angepasst.'),
        availableGroups:            templates.success.replace('${action}', 'Verfügbare Gruppen').replace('${details}', '${data}'),
        errorHandlingRequest:       templates.error.replace('${action}', 'Fehler bei der Verarbeitung der Anfrage').replace('${details}', '${error}'),
        fetchingSources:            templates.info.replace('${action}', 'Abrufen von Quellen für Gruppe: ${groupName}'),
        groupFetchError:            templates.error.replace('${action}', 'Fehler beim Abrufen der Gruppen').replace('${details}', 'Bitte versuchen Sie es später erneut.'),
        groupNameRequired: 'Gruppenname erforderlich für diese Anfrage.',
        gotGetSourceResponse:       templates.success.replace('${action}', 'Antwort auf get_source erhalten').replace('${details}', '${data}'),
        gotListGroupsResponse:      templates.success.replace('${action}', 'Antwort auf list_groups erhalten').replace('${details}', '${response}'),
        gotListSourcesResponse:     templates.success.replace('${action}', 'Antwort auf list_sources erhalten').replace('${details}', '${data}'),
        handlingToolRequest:        templates.info.replace('${action}', 'Verarbeite Tool-Anfrage: ${name}'),
        headers: 'Header: ${headers}',
        incomingMessage: '📥 Eingehende Nachricht:',
        internalServerError: 'Interner Serverfehler',
        invalidGroups:              templates.error.replace('${action}', 'Ungültige Gruppen').replace('${details}', '${groups}'),
        loginResponse:              templates.success.replace('${action}', 'Login-Antwort').replace('${details}', ''),
        makingGetSourceRequest:     templates.info.replace('${action}', 'Erstellen einer get_source-Anfrage').replace('${details}', '${args}'),
        makingListGroupsRequest:    templates.info.replace('${action}', 'Erstellen einer list_groups-Anfrage'),
        makingListSourcesRequest:   templates.info.replace('${action}', 'Erstellen einer list_sources-Anfrage').replace('${details}', '${args}'),
        mcpError:                   templates.error.replace('${action}', '[MCP Fehler]').replace('${details}', '${error}'),
        method: 'Methode: ${method}',
        payload: 'Daten: ${payload}',
        portInUse:                  templates.error.replace('${action}', 'Port Fehler').replace('${details}', 'Port ${PORT} ist bereits in Verwendung.'),
        portInvalid:                templates.error.replace('${action}', 'Port Fehler').replace('${details}', 'PORT muss eine Zahl zwischen 1 und 65535 sein.'),
        portValidated:              templates.success.replace('${action}', 'PORT erfolgreich validiert').replace('${details}', '${port}'),
        requestError:               templates.error.replace('${action}', 'Anfragefehler').replace('${details}', '${error}'),
        requestSent:                templates.info.replace('${action}', 'Anfrage gesendet'),
        responseError:              templates.error.replace('${action}', 'Fehler bei der Antwort').replace('${details}', '${error}'),
        responseReceived:           templates.success.replace('${action}', 'Antwort erhalten').replace('${details}', '${response}'),
        serverError:                templates.error.replace('${action}', 'Server-Fehler').replace('${details}', '${error}'),
        sendingChatRequest:         templates.info.replace('${action}', 'Senden einer Chat-Anfrage an die API'),
        sourcesRetrieved:           templates.success.replace('${action}', 'Quellen erhalten').replace('${details}', '${data}'),
        tcpServerError:             templates.error.replace('${action}', 'TCP Server Fehler').replace('${details}', '${error}'),
        restrictedGroupsError:      templates.error.replace('${action}', 'Ungültige RESTRICTED_GROUPS-Konfiguration').replace('${details}', "muss 'true' oder 'false' sein. Aktueller Wert: ${value}"),
        restrictedGroupsSuccess:    templates.success.replace('${action}', 'RESTRICTED_GROUPS').replace('${details}', 'ist aktiviert: ${status}'),
        toolDisabledError: templates.error.replace('${action}', 'Tool deaktiviert').replace('${details}', 'Die Funktion "${toolName}" ist auf dem Server deaktiviert.'),
        sslValidationSet:           '${symbol} SSL-Validierung ist eingestellt auf: ${value}',
        startingServerWithConfig:   templates.configStart.replace('${action}', 'Starten des Servers').replace('${details}', 'mit folgender Konfiguration:\n${config}'),
        serverRunning: templates.info.replace('${action}', 'Server läuft').replace('${details}', 'auf Port ${port}'),
        connection: {
            new: '📥 Neue Verbindung akzeptiert von ${ip}:${port}',
            established: '🚀 Verbindung hergestellt',
            closed: '🔌 Verbindung geschlossen: ${ip}:${port}',
            dataReceived: '📥 Empfangene Daten von ${ip}:${port}: ${data}',
        },
        errors: {
            processMessage: '❌ Fehler bei der Verarbeitung der Nachricht: ${error}',
            invalidMessage: 'Ungültiges Nachrichtenformat',
            socketError: '❌ Socket-Fehler bei ${ip}:${port}: ${error}',
            serverError: '❌ Server-Fehler: ${error}',
        },
        server: {
            running: '📡 Server läuft auf Port ${port}',
            stopped: '🛑 Server wurde gestopped',
        },
        loginSuccess: '✔️ Login erfolgreich: ${data}',
        invalidArgumentsError: '❌ Fehler: Keine gültigen Argumente in der Eingabe gefunden: ${input}',
        missingArgumentsError: '❌ Fehlende Argumente: ${args}',
        noTokenError: '❌ Kein Token bereitgestellt.',
        publicGroupsConflictWarning: '⚠️ Konflikt: usePublic wurde auf false gesetzt, da Gruppen angegeben sind.',
        sendingChatRequest: '📤 Sende Chat-Anfrage: Frage: "${question}", Öffentlich: ${usePublic}, Gruppen: ${groups}, Sprache: ${language}',
        checkingGroups: '📤 Überprüfen der Gruppen: ${groups}',
        invalidGroupsError: '❌ Ungültige Gruppen gefunden: ${invalidGroups}',
        availableGroups: '✔️ Verfügbare Gruppen: ${availableGroups}',
        groupValidationError: '❌ Fehler bei der Gruppenvalidierung: ${error}',
         loginError: '❌ Fehler beim Login: ${error}',
        logoutSuccess: '✔️ Logout erfolgreich: ${data}',
        logoutError: '❌ Fehler beim Logout: ${error}',
        chatResponseSuccess: '✔️ Chat-Antwort erfolgreich erhalten: ${data}',
        chatApiError: '❌ Fehler bei der Chat-API-Anfrage: ${error}',
        conversationContinuation: '✔️ Fortsetzung der Konversation mit ID: ${chatId}',
        conversationSuccess: '✔️ Konversation erfolgreich fortgesetzt: ${data}',
        apiRequestError: '❌ Fehler bei der API-Anfrage: ${error}',
        noChatData: 'Keine Daten für den angegebenen Chat gefunden.',
        fetchChatInfoError: '❌ Fehler beim Abrufen der Chat-Informationen: ${error}',
        missingTokenError: 'Token fehlt. Bitte einloggen und erneut versuchen.',
        missingParametersError: 'Fehlende erforderliche Parameter: ${parameters}.',
        invalidGroupsError: 'Ungültige Gruppen: ${invalidGroups}',
        createSourceSuccess: '✔️ Quelle erfolgreich erstellt: ${data}',
        createSourceError: '❌ Fehler beim Erstellen der Quelle: ${error}',
        noServerResponse: 'Keine Antwort vom Server erhalten.',
        missingParameterError: 'Fehlender erforderlicher Parameter: ${parameter}.',
        editSourceSuccess: '✔️ Quelle erfolgreich bearbeitet: ${data}',
        editSourceError: '❌ Fehler beim Bearbeiten der Quelle: ${error}',
        deleteSourceError: '❌ Fehler beim Löschen der Quelle: ${error}',
        storeGroupLog: 'Speichere neue Gruppe mit Name: ${groupName} und Beschreibung: ${description}',
        storeGroupSuccess: 'Gruppe erfolgreich gespeichert: ${data}',
        storeGroupText: 'Gruppe "${groupName}" erfolgreich gespeichert mit ID: ${id}',
        deleteGroupLog: 'Lösche Gruppe mit Name: ${groupName}',
        deleteGroupSuccessLog: 'Gruppe erfolgreich gelöscht: ${data}',
        deleteGroupText: 'Gruppe "${groupName}" wurde erfolgreich gelöscht.',
        apiRequestError: 'Fehler bei der API-Anfrage: ${error}',
        createUserError: '❌ Fehler beim Erstellen des Benutzers: ${error}',
        editUserError: '❌ Fehler beim Bearbeiten des Benutzers: ${error}',
        deleteUserError: '❌ Fehler beim Löschen des Benutzers: ${error}',
        deleteUserSuccess: '✔️ Benutzer erfolgreich gelöscht: ${data}',
        editUserSuccess: '✔️ Benutzer erfolgreich bearbeitet: ${data}',
        createUserSuccess: '✔️ Benutzer erfolgreich erstellt: ${data}',
        createUserLog: '📤 Erstellen eines neuen Benutzers: ${payload}',
        createGroupSuccess: '✔️ Gruppe erfolgreich erstellt: ${data}',
        fetchGroupsError: '❌ Fehler beim Abrufen der Gruppen: ${error}',
        apiRequestError: '❌ Fehler bei der API-Anfrage: ${error}',
        restrictedGroupsWarning: '⚠️ RESTRICTED_GROUPS aktiviert. Verfügbare Gruppen werden eingeschränkt.',
        editSourceLog: 'Bearbeite Quelle mit ID: ${sourceId}, Titel: ${title}',
    },
    en: {
        editSourceLog: 'Editing source with ID: ${sourceId}, Title: ${title}',
        fetchGroupsError: '❌ Error fetching groups: ${error}',
        apiRequestError: '❌ Error during API request: ${error}',
        restrictedGroupsWarning: '⚠️ RESTRICTED_GROUPS enabled. Available groups are restricted.',
        deleteUserSuccess: '✔️ User successfully deleted: ${data}',
        editUserSuccess: '✔️ User successfully edited: ${data}',
        createUserSuccess: '✔️ User successfully created: ${data}',
        createUserLog: '📤 Creating a new user: ${payload}',
        createGroupSuccess: '✔️ Group successfully created: ${data}',
        deleteSourceError: '❌ Error deleting source: ${error}',
        storeGroupLog: 'Storing new group with name: ${groupName} and description: ${description}',
        storeGroupSuccess: 'Group stored successfully: ${data}',
        storeGroupText: 'Group "${groupName}" successfully stored with ID: ${id}',
        deleteGroupLog: 'Deleting group with name: ${groupName}',
        deleteGroupSuccessLog: 'Group successfully deleted: ${data}',
        deleteGroupText: 'Group "${groupName}" was successfully deleted.',
        apiRequestError: 'Error during API request: ${error}',
        createUserError: '❌ Error creating user: ${error}',
        editUserError: '❌ Error editing user: ${error}',
        deleteUserError: '❌ Error deleting user: ${error}',
        missingTokenError: 'Token is missing. Please log in and try again.',
        missingParametersError: 'Missing required parameters: ${parameters}.',
        invalidGroupsError: 'Invalid groups: ${invalidGroups}',
        createSourceSuccess: '✔️ Source successfully created: ${data}',
        createSourceError: '❌ Error creating the source: ${error}',
        noServerResponse: 'No response received from the server.',
        missingParameterError: 'Missing required parameter: ${parameter}.',
        editSourceSuccess: '✔️ Source successfully edited: ${data}',
        editSourceError: '❌ Error editing the source: ${error}',
        loginError: '❌ Error during login: ${error}',
        logoutSuccess: '✔️ Logout successful: ${data}',
        logoutError: '❌ Error during logout: ${error}',
        chatResponseSuccess: '✔️ Chat response successfully received: ${data}',
        chatApiError: '❌ Error during chat API request: ${error}',
        conversationContinuation: '✔️ Continuing conversation with ID: ${chatId}',
        conversationSuccess: '✔️ Conversation successfully continued: ${data}',
        apiRequestError: '❌ Error during API request: ${error}',
        noChatData: 'No data found for the specified chat.',
        fetchChatInfoError: '❌ Error fetching chat information: ${error}',
        checkingGroups: '📤 Checking groups: ${groups}',
        invalidGroupsError: '❌ Invalid groups found: ${invalidGroups}',
        availableGroups: '✔️ Available groups: ${availableGroups}',
        groupValidationError: '❌ Error during group validation: ${error}',
        missingArgumentsError: '❌ Missing arguments: ${args}',
        invalidArgumentsError: '❌ Error: No valid arguments found in the input: ${input}',
        loginSuccess: '✔️ Login successful: ${data}',
        sslValidationSet: '${symbol} SSL validation is set to: ${value}',
        serverRunning: templates.info.replace('${action}', 'Server is running').replace('${details}', 'on port ${port}'),
        toolDisabledError: templates.error.replace('${action}', 'Tool disabled').replace('${details}', 'The feature "${toolName}" is disabled on the server.'),
        restrictedGroupsError:      templates.error.replace('${action}', 'Invalid RESTRICTED_GROUPS configuration').replace('${details}', "must be 'true' or 'false'. Current value: ${value}"),
        restrictedGroupsSuccess:    templates.success.replace('${action}', 'RESTRICTED_GROUPS').replace('${details}', 'is enabled: ${status}'),
        apiErrorDetails:            templates.error.replace('${action}', 'API Error').replace('${details}', 'Status: ${status}, Data: ${data}'),
        apiUrlInvalid:              templates.error.replace('${action}', 'Invalid API_URL').replace('${details}', ''),
        apiUrlValidated:            templates.success.replace('${action}', 'API_URL successfully validated').replace('${details}', '${url}'),
        apiUrlWarning:              templates.warning.replace('${action}', 'Warning').replace('${details}', 'API_URL does not start with "https://". The URL will be adjusted.'),
        apiUrlWarningV1:            templates.warning.replace('${action}', 'Warning').replace('${details}', 'API_URL does not end with "/api/v1". The URL will be adjusted.'),
        availableGroups:            templates.success.replace('${action}', 'Available groups').replace('${details}', '${data}'),
        errorHandlingRequest:       templates.error.replace('${action}', 'Error handling request').replace('${details}', '${error}'),
        fetchingSources:            templates.info.replace('${action}', 'Fetching sources for group: ${groupName}'),
        groupFetchError:            templates.error.replace('${action}', 'Error fetching groups').replace('${details}', 'Please try again later.'),
        groupNameRequired: 'Group name is required for this request.',
        gotGetSourceResponse:       templates.success.replace('${action}', 'Got get_source response').replace('${details}', '${data}'),
        gotListGroupsResponse:      templates.success.replace('${action}', 'Got list_groups response').replace('${details}', '${response}'),
        gotListSourcesResponse:     templates.success.replace('${action}', 'Got list_sources response').replace('${details}', '${data}'),
        handlingToolRequest:        templates.info.replace('${action}', 'Handling tool request: ${name}'),
        headers: 'Headers: ${headers}',
        incomingMessage: '📥 Incoming message:',
        internalServerError: 'Internal server error',
        invalidGroups:              templates.error.replace('${action}', 'Invalid groups').replace('${details}', '${groups}'),
        loginResponse:              templates.success.replace('${action}', 'Login response').replace('${details}', ''),
        makingGetSourceRequest:     templates.info.replace('${action}', 'Making get_source request').replace('${details}', '${args}'),
        makingListGroupsRequest:    templates.info.replace('${action}', 'Making list_groups request'),
        makingListSourcesRequest:   templates.info.replace('${action}', 'Making list_sources request').replace('${details}', '${args}'),
        mcpError:                   templates.error.replace('${action}', '[MCP Error]').replace('${details}', '${error}'),
        method: 'Method: ${method}',
        payload: 'Payload: ${payload}',
        portInUse:                  templates.error.replace('${action}', 'Port Error').replace('${details}', 'Port ${PORT} is already in use.'),
        portInvalid:                templates.error.replace('${action}', 'Port Error').replace('${details}', 'PORT must be a number between 1 and 65535.'),
        portValidated:              templates.success.replace('${action}', 'PORT successfully validated').replace('${details}', '${port}'),
        requestError:               templates.error.replace('${action}', 'Request Error').replace('${details}', '${error}'),
        requestSent:                templates.info.replace('${action}', 'Request sent'),
        responseError:              templates.error.replace('${action}', 'Response error').replace('${details}', '${error}'),
        responseReceived:           templates.success.replace('${action}', 'Response received').replace('${details}', '${response}'),
        serverError:                templates.error.replace('${action}', 'Server Error').replace('${details}', '${error}'),
        sendingChatRequest:         templates.info.replace('${action}', 'Sending a chat request to the API'),
        sourcesRetrieved:           templates.success.replace('${action}', 'Sources retrieved').replace('${details}', '${data}'),
        startingServerWithConfig:   templates.warning.replace('${action}', 'Starting the server').replace('${details}', 'with the following configuration:'),
        tcpServerError:             templates.error.replace('${action}', 'TCP Server Error').replace('${details}', '${error}'),
        connection: {
            new: '📥 New connection accepted from ${ip}:${port}',
            established: '🚀 Connection established',
            closed: '🔌 Connection closed: ${ip}:${port}',
            dataReceived: '📥 Received data from ${ip}:${port}: ${data}',
        },
        errors: {
            processMessage: '❌ Error while processing the message: ${error}',
            invalidMessage: 'Invalid message format',
            socketError: '❌ Socket error for ${ip}:${port}: ${error}',
            serverError: '❌ Server error: ${error}',
        },
        server: {
            running: '📡 Server runs on port ${port}',
            stopped: '🛑 Server stopped',
        },
    }
};

// JSON-Datei laden
// `__dirname`-Ersatz für ES-Module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// JSON-Dateipfad relativ zum Skript
const envFilePath = path.resolve(__dirname, '../pgpt.env.json');
let envConfig;

try {
    envConfig = JSON.parse(fs.readFileSync(envFilePath, 'utf-8'));
} catch (error) {
    console.error(`❌ Error loading pgpt.env.json: ${error.message}`);
    process.exit(1);
}

// Helper-Funktionen
function getEnvVar(key, nestedPath = null, fallback = null) {
    // Prüfen, ob ein verschachtelter Pfad angegeben ist
    if (nestedPath) {
        const value = nestedPath.reduce((acc, part) => acc && acc[part], envConfig);
        if (!value) {
            if (fallback !== null) return fallback;
            console.error(`❌ Missing .json configuration variable: ${key}`);
            process.exit(1);
        }
        return value;
    }
    // Direkter Zugriff
    if (!envConfig[key]) {
        if (fallback !== null) return fallback;
        console.error(`❌ Missing .json configuration variable: ${key}`);
        process.exit(1);
    }
    return envConfig[key];
}

const privateApiUrl = getEnvVar('PRIVATE_GPT_API_URL', ['PGPT_Url', 'PRIVATE_GPT_API_URL']);
const requestedLang = getEnvVar('LANGUAGE', ['Server_Config', 'LANGUAGE'], 'en').toLowerCase();
const apiUrl = getEnvVar('API_URL', ['PGPT_Url', 'API_URL']);
const Port = getEnvVar('PORT', ['Server_Config', 'PORT'], '5000');
const restrictedGroups = getEnvVar('RESTRICTED_GROUPS', ['Restrictions', 'RESTRICTED_GROUPS'], 'false').toString();
const sslValidate = getEnvVar('SSL_VALIDATE', ['Server_Config', 'SSL_VALIDATE'], 'false').toString();
const PwEncryption = getEnvVar('PW_ENCRYPTION', ['Server_Config', 'PW_ENCRYPTION'], 'false') === 'true';
const AllowKeygen = getEnvVar('ALLOW_KEYGEN', ['Server_Config', 'ALLOW_KEYGEN'], 'false') === 'true';
const publicKeyPath = getEnvVar('PUBLIC_KEY', ['Server_Config', 'PUBLIC_KEY']);
const privateKeyPath = getEnvVar('PRIVATE_KEY', ['Server_Config', 'PRIVATE_KEY']);


// Load the public key
const publicKey = fs.readFileSync(getEnvVar('PUBLIC_KEY', ['Server_Config', 'PUBLIC_KEY']), 'utf8');

// Load the private key
const privateKey = fs.readFileSync(getEnvVar('PRIVATE_KEY', ['Server_Config', 'PRIVATE_KEY']), 'utf8');


if (PwEncryption) {
    console.log('Password encryption is enabled.');
} else {
    console.log('Password encryption is disabled.');
}

function validateUrl(url, t) {
    if (!url.startsWith('https://')) {
        console.warn(t.apiUrlWarning);
        url = url.replace(/^http:\/\//, 'https://');
    }
    url = url.replace(/([^:]\/)\/+/g, '$1'); // Doppelte Schrägstriche nach "://" entfernen
    if (!url.endsWith('/api/v1')) {
        console.warn(t.apiUrlWarningV1);
        url = `${url.replace(/\/$/, '')}/api/v1`;
    }
    try {
        new URL(url);
    } catch {
        console.error(t.apiUrlInvalid, url);
        process.exit(1);
    }
    return url;
}

function validatePort(port, t) {
    const portNumber = parseInt(port, 10);
    if (isNaN(portNumber) || portNumber < 1 || portNumber > 65535) {
        console.error(t.portInvalid);
        process.exit(1);
    }
    return portNumber;
}

function validateBoolean(varName, value, t) {
    if (value !== 'true' && value !== 'false') {
        console.error(
            t.restrictedGroupsError.replace('${value}', value)
        );
        process.exit(1);
    }
    return value === 'true';
}

/**
 * Decrypt a cryptographic string using the private key.
 * @param {string} encryptedData - The encrypted string in Base64 format.
 * @returns {string} - The decrypted password.
 */
function decryptPassword(encryptedData) {
    try {
        const decryptedPassword = crypto.privateDecrypt(
            {
                key: privateKey,
                padding: crypto.constants.RSA_PKCS1_PADDING, // Ensure consistent padding
            },
            Buffer.from(encryptedData, 'base64')
        ).toString('utf8');

        return decryptedPassword;
    } catch (error) {
        console.error('Decryption error:', error.message);
        throw new Error('Failed to decrypt the password.');
    }
}


// Function for encryption
function encryptWithPublicKey(data) {
    return crypto.publicEncrypt(
        {
            key: publicKey,
            padding: crypto.constants.RSA_PKCS1_PADDING, // Explicitly set padding
        },
        Buffer.from(data)
    ).toString('base64');
}

/**
 * Encrypt a given password and return the encrypted key.
 * @param {string} password - The password to be encrypted.
 * @returns {string} - The encrypted password as a Base64 string.
 */
function getEncryptedKey(password) {
    try {
        return encryptWithPublicKey(password);
    } catch (err) {
        console.error('Encryption error:', err.message);
        throw new Error('Failed to encrypt the password.');
    }
}

const enableLogin = getEnvVar('ENABLE_LOGIN', ['Functions', 'ENABLE_LOGIN'], false);
const enableLogout = getEnvVar('ENABLE_LOGOUT', ['Functions', 'ENABLE_LOGOUT'], false);
const enableChat = getEnvVar('ENABLE_CHAT', ['Functions', 'ENABLE_CHAT'], false);
const enableContinueChat = getEnvVar('ENABLE_CONTINUE_CHAT', ['Functions', 'ENABLE_CONTINUE_CHAT'], false);
const enableGetChatInfo = getEnvVar('ENABLE_GET_CHAT_INFO', ['Functions', 'ENABLE_GET_CHAT_INFO'], false);
const enableListGroups = getEnvVar('ENABLE_LIST_GROUPS', ['Functions', 'ENABLE_LIST_GROUPS'], false);
const enableStoreGroup = getEnvVar('ENABLE_STORE_GROUP', ['Functions', 'ENABLE_STORE_GROUP'], false);
const enableDeleteGroup = getEnvVar('ENABLE_DELETE_GROUP', ['Functions', 'ENABLE_DELETE_GROUP'], false);
const enableCreateSource = getEnvVar('ENABLE_CREATE_SOURCE', ['Functions', 'ENABLE_CREATE_SOURCE'], false);
const enableEditSource = getEnvVar('ENABLE_EDIT_SOURCE', ['Functions', 'ENABLE_EDIT_SOURCE'], false);
const enableDeleteSource = getEnvVar('ENABLE_DELETE_SOURCE', ['Functions', 'ENABLE_DELETE_SOURCE'], false);
const enableGetSource = getEnvVar('ENABLE_GET_SOURCE', ['Functions', 'ENABLE_GET_SOURCE'], false);
const enableListSources = getEnvVar('ENABLE_LIST_SOURCES', ['Functions', 'ENABLE_LIST_SOURCES'], false);
const enableStoreUser = getEnvVar('ENABLE_STORE_USER', ['Functions', 'ENABLE_STORE_USER'], false);
const enableEditUser = getEnvVar('ENABLE_EDIT_USER', ['Functions', 'ENABLE_EDIT_USER'], false);
const enableDeleteUser = getEnvVar('ENABLE_DELETE_USER', ['Functions', 'ENABLE_DELETE_USER'], false);

console.log('🌐 Server Config:', JSON.stringify(envConfig, null, 2));

console.log('✅ Private API URL:', privateApiUrl);
console.log('✅ Public API URL:', apiUrl);
console.log('✅ Port:', Port);
console.log('✅ Language:', requestedLang);
console.log('✅ SSL-validation:', sslValidate);
console.log('✅ PW_Encryption:', PwEncryption);
console.log('✅ Allow_Keygen:', AllowKeygen);
console.log('✅ Private_Key:', privateKeyPath);
console.log('✅ Public_Key:', publicKeyPath);
console.log('✅ Restricted Groups:', restrictedGroups);


// Alle Funktionen mit ihren Enable-Flags in einem Array organisieren
const allFunctions = [
  { name: 'Login', enabled: enableLogin },
  { name: 'Logout', enabled: enableLogout },
  { name: 'Chat', enabled: enableChat },
  { name: 'Continue Chat', enabled: enableContinueChat },
  { name: 'Get Chat Info', enabled: enableGetChatInfo },
  { name: 'List Groups', enabled: enableListGroups },
  { name: 'Store Group', enabled: enableStoreGroup },
  { name: 'Delete Group', enabled: enableDeleteGroup },
  { name: 'Create Source', enabled: enableCreateSource },
  { name: 'Edit Source', enabled: enableEditSource },
  { name: 'Delete Source', enabled: enableDeleteSource },
  { name: 'Get Source', enabled: enableGetSource },
  { name: 'List Sources', enabled: enableListSources },
  { name: 'Store User', enabled: enableStoreUser },
  { name: 'Edit User', enabled: enableEditUser },
  { name: 'Delete User', enabled: enableDeleteUser }
];

// Filtern, um nur deaktivierte (false) zu bekommen
const disabledFunctions = allFunctions.filter(f => !f.enabled);

// Wenn gar keine Funktionen deaktiviert sind, kurze Info ausgeben
if (disabledFunctions.length === 0) {
  console.log('✅ All functions are enabled.');
} else {
  console.log('⚠️ Deactivated functions:');
  disabledFunctions.forEach(func => {
    console.log(`  ➡️ ${func.name}: false`);
  });
}

// Nachrichten basierend auf Sprache
let lang = getEnvVar('LANGUAGE', ['Server_Config', 'LANGUAGE'], 'en').toLowerCase();
if (!(lang in messages)) {
    console.warn(`⚠️ Language "${lang}" is not supported. Fallback in English.`);
    lang = 'en';
}

const t = messages[lang];
console.log(t.apiUrlValidated.replace('${url}', apiUrl));

// Port validieren
console.log(t.portValidated.replace('${port}', Port));

// Debugging für RESTRICTED_GROUPS
console.log('🛠️ Access to RESTRICTED_GROUPS:', envConfig.Restrictions?.RESTRICTED_GROUPS);

// Zugriff und Validierung von RESTRICTED_GROUPS
const isRestrictedGroupsEnabled = validateBoolean(
    'RESTRICTED_GROUPS',
    restrictedGroups,
    t
);

console.log(
    t.restrictedGroupsSuccess.replace('${status}', isRestrictedGroupsEnabled)
);


// SSL-Validierung
const isSSLValidationEnabled = validateBoolean(
    'SSL_VALIDATE',
    getEnvVar('SSL_VALIDATE', ['Server_Config', 'SSL_VALIDATE'], 'false').toString(),
    t
);

const sslSymbol = isSSLValidationEnabled ? '✔️' : '⚠️';
console.log(
  t.sslValidationSet
    .replace('${symbol}', sslSymbol)
    .replace('${value}', String(isSSLValidationEnabled))
);
// console.log('sslValidationSet String ist:', t.sslValidationSet);

const validatedPort = validatePort(Port, t);
console.log(t.portValidated.replace('${port}', validatedPort));


// Beispiel: Tool-Überprüfung
function isToolEnabled(toolName) {
    const envKey = `ENABLE_${toolName.toUpperCase()}`;
    if (!(envKey in envConfig.Functions)) {
        console.warn(`⚠️ Tool "${toolName}" is not defined in the configuration. Default: deactivated.`);
        return false;
    }
    return envConfig.Functions[envKey] === true;
}



/* ################ Helper Functions ############################*/
// Helper-Funktion, um zu prüfen, ob ein Tool aktiviert ist, und eine Fehlermeldung zu generieren
function checkToolEnabled(toolName) {
    if (toolName === "keygen" && AllowKeygen) {
        return null;
    }
        
    if (!isToolEnabled(toolName)) {
        return {
            status: 'error',
            message: messages[lang].toolDisabledError.replace('${toolName}', toolName),
        };
    }
    return null; // Tool ist aktiviert
}

function validateToken(token) {
    if (!token) {
        return {
            status: 'error',
            message: 'Token fehlt. Bitte einloggen und erneut versuchen.',
            statusCode: 401 // Optional für konsistenten HTTP-Status
        };
    }
    return null;
}

function getArguments(input) {
    if (input.arguments) {
        return input.arguments;
    } else if (input.params?.arguments) {
        return input.params.arguments;
    } else {
        console.error(t.invalidArgumentsError.replace('${input}', JSON.stringify(input)));
        return {}; // Leeres Objekt als Fallback
    }
}

// Parameter zuordnen
const API_URL = apiUrl;
const PORT = Port;

// Server-Startkonfiguration ausgeben
const serverConfig = JSON.stringify({ API_URL, PORT }, null, 2);
console.log(
    messages[lang].startingServerWithConfig
        .replace('${config}', serverConfig)
);

//const net = require('net');

class TcpServerTransport {
    constructor(port) {
        this.port = port;
        this.server = null;
        this.clients = new Map(); // Map zur Speicherung der Clients
    }

    async start(onMessage) {
        return new Promise((resolve, reject) => {
            // Server erstellen
            this.server = net.createServer((socket) => {
                const clientIP = socket.remoteAddress || 'unbekannt';
                const clientPort = socket.remotePort || 'unbekannt';

                // Client-Informationen in der Map speichern
                this.clients.set(socket, { ip: clientIP, port: clientPort });
                
                console.log(t.connection.new.replace('${ip}', clientIP).replace('${port}', clientPort));

                // Ereignis: Daten empfangen
                socket.on('data', async (data) => {
                    const client = this.clients.get(socket);
                    console.log(t.connection.dataReceived
                        .replace('${ip}', client.ip)
                        .replace('${port}', client.port)
                        .replace('${data}', data.toString()));
                    try {
                        const message = JSON.parse(data.toString());
                        const response = await onMessage(message);
                        socket.write(JSON.stringify(response));
                    } catch (err) {
                        console.error(t.errors.processMessage.replace('${error}', err.message || err));
                        socket.write(JSON.stringify({ error: t.errors.invalidMessage }));
                    }
                });

                // Ereignis: Verbindung geschlossen
                socket.on('close', () => {
                    const client = this.clients.get(socket);
                    console.log(t.connection.closed.replace('${ip}', client.ip).replace('${port}', client.port));
                    this.clients.delete(socket); // Client aus der Map entfernen
                });

                // Fehlerbehandlung für einzelne Sockets
                socket.on('error', (err) => {
                    const client = this.clients.get(socket);
                    console.error(t.errors.socketError
                        .replace('${ip}', client?.ip || 'unknown')
                        .replace('${port}', client?.port || 'unknown')
                        .replace('${error}', err.message || err));
                });

                // Server-Ereignis: Verbindung hergestellt
                this.server.on('connection', (socket) => {
                    console.log(t.connection.established);
                    socket.setKeepAlive(true, 30000); // Keep-Alive für jede Verbindung setzen
                });
            });

            // Server starten
            this.server.listen(this.port, () => {
                console.log(t.server.running.replace('${port}', this.port));
                resolve();
            });

            // Server-Ereignis: Fehler
            this.server.on('error', (err) => {
                console.error(t.errors.serverError.replace('${error}', err.message || err));
                reject(err);
            });
        });
    }

    async stop() {
        if (this.server) {
            this.server.close(() => {
                console.error(t.server.stopped);
                this.clients.clear(); // Alle Clients aus der Map entfernen
            });
        }
    }
}

class PrivateGPTServer {
    server;
    axiosInstance;
    authToken = null; // Initialisierung des Authentifizierungs-Tokens
    authTokenTimestamp = 0; // Initialisierung des Zeitstempels für Token-Gültigkeit

    constructor() {
        this.server = new Server({
            name: 'pgpt-mcp-server',
            version: '2.1.0',
        }, {
            capabilities: {
                resources: {},
                tools: {},
            },
        });

        // Create axios instance with SSL disabled for development
        this.axiosInstance = axios.create({
            baseURL: API_URL,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            httpsAgent: new https.Agent({
                rejectUnauthorized: isSSLValidationEnabled // Dynamisch durch SSL_VALIDATE gesteuert
            })
        });
        
    // console.log(t.sslValidationSet.replace('${value}', sslValidate));
        // Interceptors for logging requests and responses
        this.axiosInstance.interceptors.request.use((config) => {
            console.log(t.requestSent);
            console.log('URL:', config.baseURL + config.url);
            console.log('Method:', config.method.toUpperCase());
            console.log('Headers:', config.headers);
            if (config.data) {
                console.log('Payload:', config.data);
            }
            return config;
        },  (error) => {
                  console.error(t.requestError.replace('${error}', error.message || error));
            return Promise.reject(error);
        });
    
       this.axiosInstance.interceptors.response.use((response) => {
            console.log(t.responseReceived);
            console.log('Status:', response.status);
            console.log('Data:', response.data);
            return response;
        }, (error) => {
            console.error(t.responseError, error.response ? error.response.data : error.message);
            return Promise.reject(error);
        });

        this.setupResourceHandlers();
        this.setupToolHandlers();

        // Error handling
        this.server.onerror = (error) => {
            console.error(t.mcpError.replace('${error}', error.message || JSON.stringify(error, null, 2)));
        };

        process.on('SIGINT', async () => {
            await this.server.close();
            process.exit(0);
        });
    }
        // Neue Login-Funktion
        async login(email, password) {
            console.error(`Authenticating user: ${email}`);
            try {
                const loginResponse = await this.axiosInstance.post('/login', {
                    email,
                    password
                });

                console.error('Login response:', loginResponse.data);

                // Rückgabe des Tokens
                return loginResponse.data.data.token;
            } catch (error) {
                console.error('Login error:', error.message || error);
                throw new Error('Authentication failed');
            }
        }

        // ensureAuthenticated nutzt die neue login-Funktion
        async ensureAuthenticated(token) {
            if (!token) {
                console.error('Fehlendes Token. Bitte zuerst einloggen.');
                throw new Error('Fehlendes Token.');
            }

            console.log('Setting token for authentication...');
            // Setze das Token als Authorization-Header
            this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
            console.log('Token erfolgreich gesetzt.');
        }

        isTokenExpired() {
            // Beispielprüfung: Token sollte innerhalb einer Stunde erneuert werden
            const EXPIRATION_THRESHOLD = 3600 * 1000; // 1 Stunde
            const now = Date.now();
            const tokenAge = now - this.authTokenTimestamp;
            return tokenAge >= EXPIRATION_THRESHOLD;
        }
        async validateGroups(groups, token) {
            try {
                console.log(t.checkingGroups.replace('${groups}', JSON.stringify(groups)));

                // Sicherstellen, dass der Token gesetzt ist
                if (!token) {
                    throw new Error('Token fehlt. Kann Gruppen nicht validieren.');
                }

                // Temporär den Header setzen, falls global nicht vorhanden
                const response = await this.axiosInstance.get('/groups', {
                    headers: { Authorization: `Bearer ${token}` }
                });

                const availableGroups = response.data?.data?.assignableGroups || [];
                console.log(t.availableGroups.replace('${availableGroups}', JSON.stringify(availableGroups)));

                // Überprüfen, ob die übergebenen Gruppen gültig sind
                const invalidGroups = groups.filter(group => !availableGroups.includes(group));
                if (invalidGroups.length > 0) {
                    console.error(t.invalidGroupsError.replace('${invalidGroups}', JSON.stringify(invalidGroups)));
                    return { isValid: false, invalidGroups };
                }

                return { isValid: true };
            } catch (error) {
                const errorMessage = error.response?.data || error.message;
                console.error(t.groupValidationError.replace('${error}', errorMessage));
                throw new Error(error.response?.data?.message || 'Fehler beim Abrufen der Gruppen.');
            }
        }

    setupResourceHandlers() {
        // List available resources
        this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
            resources: []
        }));
        // List resource templates
        this.server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
            resourceTemplates: []
        }));
        // Read resource
        this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
            if (!request.params?.uri) {
                throw new McpError(ErrorCode.InvalidRequest, 'Missing URI parameter');
            }
            throw new McpError(ErrorCode.InvalidRequest, `Invalid URI: ${request.params.uri}`);
        });
    }
    setupToolHandlers() {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
        tools: [
            {   /* 1.0 Login #####################################################################################*/
                name: 'login',
                description: 'User login to retrieve an API token',
                inputSchema: {
                    type: 'object',
                    properties: {
                        email: {
                            type: 'string',
                            description: 'User email address for login'
                        },
                        password: {
                            type: 'string',
                            description: 'User password for login'
                        }
                    },
                    required: ['email', 'password']
                }
            },
            {   /* 1.1 Logout ####################################################################################*/
                name: 'logout',
                description: 'Invalidate the API token',
                inputSchema: { type: 'object', properties: {} },
            },
            {   /* 2.0 Chat ######################################################################################*/
                name: 'chat',
                description: 'Start or continue a chat with PrivateGPT with optional RAG capabilities',
                inputSchema: {
                    type: 'object',
                    properties: {
                        question: { type: 'string', description: 'The question or prompt to send' },
                        usePublic: { type: 'boolean', description: 'Use public knowledge base', default: false },
                        groups: {
                            type: 'array',
                            items: { type: 'string' },
                            description: 'Group names for RAG (exclusive with usePublic)',
                        },
                        language: { type: 'string', description: 'Language code (e.g., "en")', default: 'en' },
                    },
                    required: ['question'],
                },
            },
            {   /* 2.1 Continue Chat #############################################################################*/
                name: 'continue_chat',
                description: 'Continue an existing chat',
                inputSchema: {
                    type: 'object',
                    properties: {
                        chatId: { type: 'string', description: 'ID of the existing chat to continue' },
                        question: { type: 'string', description: 'The next question or message in the chat' },
                    },
                    required: ['chatId', 'question'],
                },
            },
            {   /* 2.2 Get Chat Info #############################################################################*/
                name: 'get_chat_info',
                description: 'Retrieve details about an existing chat using its ID',
                inputSchema: {
                    type: 'object',
                    properties: {
                        chatId: { type: 'string', description: 'ID of the chat to retrieve details for' },
                        token: { type: 'string', description: 'Authorization token for API access' },
                    },
                    required: ['chatId', 'token'],
                },
            },
            {   /* 3.0 Create Source #############################################################################*/
                name: 'create_source',
                description: 'Create a new source with automatic markdown formatting',
                inputSchema: {
                    type: 'object',
                    properties: {
                        name: { type: 'string', description: 'Name of the source' },
                        content: { type: 'string', description: 'Markdown-formatted content' },
                        groups: {
                            type: 'array',
                            items: { type: 'string' },
                            description: 'Optional groups to assign the source to',
                        },
                    },
                    required: ['name', 'content'],
                },
            },
            {   /* 3.1 Get Source ################################################################################*/
                name: 'get_source',
                description: 'Retrieve information about a specific source',
                inputSchema: {
                    type: 'object',
                    properties: {
                        sourceId: { type: 'string', description: 'ID of the source to retrieve' },
                    },
                    required: ['sourceId'],
                },
            },
            {   /* 3.2 List Sources ##############################################################################*/
                name: 'list_sources',
                description: 'List all sources in a specific group',
                inputSchema: {
                    type: 'object',
                    properties: {
                        groupName: { type: 'string', description: 'Group name to list sources from' },
                    },
                    required: ['groupName'],
                },
            },
            {   /* 3.3 Edit Source ###############################################################################*/
                name: 'edit_source',
                description: 'Edit an existing source',
                inputSchema: {
                    type: 'object',
                    properties: {
                        sourceId: {
                            type: 'string',
                            description: 'ID of the source to edit'
                        },
                        token: {
                            type: 'string',
                            description: 'Authorization token for API access'
                        },
                        title: {
                            type: 'string',
                            description: 'New title for the source (optional)'
                        },
                        content: {
                            type: 'string',
                            description: 'New markdown-formatted content for the source (optional)'
                        },
                        groups: {
                            type: 'array',
                            items: {
                                type: 'string'
                            },
                            description: 'Updated group(s) to assign to the source (optional)'
                        }
                    },
                    required: ['sourceId', 'token']
                }
            },
            {   /* 3.4 Delete Source #############################################################################*/
                name: 'delete_source',
                description: 'Delete a specific source',
                inputSchema: {
                    type: 'object',
                    properties: {
                        sourceId: { type: 'string', description: 'ID of the source to delete' },
                    },
                    required: ['sourceId'],
                },
            },
            {   /* 4.0 List Groups ###############################################################################*/
                name: 'list_groups',
                description: 'Retrieve personal and assignable groups',
                inputSchema: { type: 'object', properties: {} },
            },
            {   /* 4.1 Store Group ###############################################################################*/
                name: 'store_group',
                description: 'Create a new group',
                inputSchema: {
                    type: 'object',
                    properties: {
                        groupName: { type: 'string', description: 'Name of the new group' },
                        description: { type: 'string', description: 'Description of the new group' },
                    },
                    required: ['groupName'],
                },
            },
            {   /* 4.2 Delete Group ##############################################################################*/
                name: 'delete_group',
                description: 'Delete an existing group',
                inputSchema: {
                    type: 'object',
                    properties: {
                        groupName: { type: 'string', description: 'Name of the group to delete' },
                    },
                    required: ['groupName'],
                },
            },
            {   /* 5.0 Store User ################################################################################*/
                name: 'store_user',
                description: 'Create a new user',
                inputSchema: {
                    type: 'object',
                    properties: {
                        name: { type: 'string', description: 'Name of the user' },
                        email: { type: 'string', description: 'Email of the user' },
                        password: { type: 'string', description: 'Password for the user' },
                        language: { type: 'string', description: 'Preferred language (optional)', default: 'en' },
                        timezone: { type: 'string', description: 'Timezone (optional)', default: 'Europe/Berlin' },
                        roles: {
                            type: 'array',
                            items: { type: 'string' },
                            description: 'Roles to assign (optional)'
                        },
                        groups: {
                            type: 'array',
                            items: { type: 'string' },
                            description: 'Groups to assign (optional)'
                        },
                        usePublic: { type: 'boolean', description: 'Enable public knowledge (optional)', default: false }
                    },
                    required: ['name', 'email', 'password']
                },
            },
            {   /* 5.1 Edit User #################################################################################*/
                name: 'edit_user',
                description: 'Edit an existing user',
                inputSchema: {
                    type: 'object',
                    properties: {
                        email: { type: 'string', description: 'Email of the user to edit' },
                        name: { type: 'string', description: 'New name for the user (optional)' },
                        password: { type: 'string', description: 'New password for the user (optional)' },
                        language: { type: 'string', description: 'Preferred language (optional)' },
                        timezone: { type: 'string', description: 'Timezone (optional)' },
                        roles: {
                            type: 'array',
                            items: { type: 'string' },
                            description: 'Updated roles (optional)'
                        },
                        groups: {
                            type: 'array',
                            items: { type: 'string' },
                            description: 'Updated groups (optional)'
                        },
                        usePublic: { type: 'boolean', description: 'Enable public knowledge (optional)' }
                    },
                    required: ['email']
                }
            },
            {   /* 5.2 Delete User ###############################################################################*/
                name: 'delete_user',
                description: 'Delete an existing user',
                inputSchema: {
                    type: 'object',
                    properties: {
                        email: { type: 'string', description: 'Email of the user to delete' }
                    },
                    required: ['email']
                }
            }
        ],
    }));
        this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
            if (!request.params?.name) {
                throw new McpError(ErrorCode.InvalidRequest, 'Missing tool name');
            }
            try {
                //await this.ensureAuthenticated();
                console.error(t.handlingToolRequest.replace('${name}', request.params.name), request.params);
                switch (request.params.name) {
                /*  1.0 Login ######################################################################################*/
                    case 'login': { 
                        const disabledResponse = checkToolEnabled('login');
                        if (disabledResponse) return disabledResponse;
                        
                        const { email, password } = request.params.arguments; // Extrahiere email und password aus der Nachricht

                        if (!email || !password) {
                            return {
                                status: 'E10-R-1000',
                                message: 'Login fehlgeschlagen: E-Mail und Passwort sind erforderlich.',
                            };
                        }

                        try {
                            // Aufruf des Login-Endpunkts der API
                            const loginResponse = await this.axiosInstance.post('/login', { email, password });

                            console.log(t.loginSuccess.replace('${data}', JSON.stringify(loginResponse.data)));
;

                            // Token zurückgeben
                            return {
                                status: loginResponse.data?.status || 'ok', // Dynamisch, falls der API-Status einheitlich ist
                                message: loginResponse.data?.message || 'Login erfolgreich.', // API-Nachricht verwenden oder Standardnachricht
                                token: loginResponse.data?.data?.token, // Token aus API-Antwort
                            };
                        } catch (error) {
                            const errorMessage = error.response?.data || error.message;
                            console.error(t.loginError.replace('${error}', errorMessage));

                            return {
                                status: error.response?.status || 'E10-R-1001', // API-Fehlerstatus oder Standardfehlerstatus,
                                message: error.response?.data?.message || 'Login fehlgeschlagen.',
                            };
                        }
                    }
                /*  1.1 Logout #####################################################################################*/
                    case 'logout': {
                        const disabledResponse = checkToolEnabled('logout');
                        if (disabledResponse) return disabledResponse;

                        const { token } = message;
                        //const { token, arguments: args } = request.params;

                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;


                        try {
                            const logoutResponse = await this.axiosInstance.delete('/logout', {
                                headers: {
                                    Authorization: `Bearer ${token}`
                                }
                            });

                            console.log(t.logoutSuccess.replace('${data}', JSON.stringify(logoutResponse.data)));


                             return {
                                data: {}, // Optional: Zusätzliche Daten könnten hier eingefügt werden
                                message: 'success',
                                status: 200, // OK
                            };
                        } catch (error) {
                            const logoutErrorMessage = error.response?.data || error.message;
                            console.error(t.logoutError.replace('${error}', logoutErrorMessage));
                            return {
                                data: {},
                                message: error.response?.data?.message || 'Logout fehlgeschlagen. Bitte versuchen Sie es später erneut.',
                                status: error.response?.status || 'E11-R-1100', // Internal Server Error oder spezifischer Statuscode
                            };
                        }
                    }
                /*  2.0 Chat #######################################################################################*/
                    case 'chat': {
                        const disabledResponse = checkToolEnabled('chat');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = request.params;
                        console.log('Extrahierter Token:', token);


                        // Token prüfen und validieren
                        if (!token) {
                            console.error(t.noTokenError);
                            return { status: 'E20-R-2000', message: t.missingTokenError };
                        }

                        /*const tokenValidation = validateToken(token);
                        if (tokenValidation) {
                            console.error('❌ Token-Validierung fehlgeschlagen. Token:', token, 'Fehler:', tokenValidation);
                            return {
                                status: 'error',
                                message: 'Token ist ungültig oder abgelaufen. Bitte erneut einloggen.',
                            };
                        }*/

                        // Argument-Validierung
                        if (!args || !args.question) {
                            console.error(t.missingArgumentsError.replace('${args}', JSON.stringify(args)));
                            return {
                                status: 'error',
                                message: t.missingArgumentsError.replace('${args}', JSON.stringify(args)),
                            };
                        }

                        const { question, usePublic, groups, language } = args;

                        // Konflikt zwischen `usePublic` und `groups` lösen
                        if (usePublic && groups && groups.length > 0) {
                            console.warn(t.publicGroupsConflictWarning);
                            args.usePublic = false;
                        }

                        try {
                            console.log(t.sendingChatRequest
                                .replace('${question}', question)
                                .replace('${usePublic}', usePublic)
                                .replace('${groups}', JSON.stringify(groups))
                                .replace('${language}', language)
                            );

                            const response = await this.axiosInstance.post(
                                '/chats',
                                {
                                    question,
                                    usePublic: usePublic || false,
                                    groups: Array.isArray(groups) ? groups : [groups],
                                    language: language || 'de',
                                },
                                { headers: { Authorization: `Bearer ${token}` } }
                            );

                            const data = response.data?.data || {};
                            console.log(t.chatResponseSuccess.replace('${data}', JSON.stringify(data)));

                            // Erfolgsantwort mit Status und Daten
                            return {
                                status: response.data?.status || 'ok',
                                message: response.data?.message || 'Chat erfolgreich.',
                                content: {
                                    chatId: data.chatId,
                                    answer: data.answer,
                                    sources: data.sources || [],
                                },
                            };
                        } catch (error) {
                            const chatApiErrorMessage = error.message || error.response?.data;
                            console.error(t.chatApiError.replace('${error}', chatApiErrorMessage));

                            // Fehlerantwort mit Status und Nachricht
                            return {
                                status: error.response?.status || 'E20-R-2002',
                                message: error.response?.data?.message || 'Fehler bei der Chat-Anfrage.',
                            };
                        }
                    }
                /*  2.1 Continue Chat ##############################################################################*/
                    case 'continue_chat': {
                        const disabledResponse = checkToolEnabled('continue_chat');
                        if (disabledResponse) return disabledResponse;

                        const args = request.params.arguments;

                        if (!args || !args.chatId || !args.question) {
                            return { status: 'E21-R-2100', message: 'Fehlende erforderliche Parameter: chatId und/oder question.' };
                        }

                        const { chatId, question } = args;
                        console.log(t.conversationContinuation.replace('${chatId}', chatId));

                        try {
                            const continueChatResponse = await this.axiosInstance.patch(`/chats/${chatId}`, {
                                question: question,
                            });
                            console.log(t.conversationSuccess.replace('${data}', JSON.stringify(continueChatResponse.data, null, 2)));
                            return {
                                content: {
                                    chatId:  continueChatResponse.data.data.chatId,
                                    answer:  continueChatResponse.data.data.answer,
                                    sources: continueChatResponse.data.sources || [],
                                    message: continueChatResponse.data.message,
                                    status:  continueChatResponse.data.status,
                                },
                            };
                        } catch (error) {
                            console.error(t.apiRequestError.replace('${error}', error.message));
                            return {
                                status: error.response?.status || 'E21-R-2101',
                                message: error.response?.data?.message || 'Fehler beim Fortsetzen der Konversation.',
                            };
                        }
                    }
                /*  2.2 Get Chat Info ##############################################################################*/
                    case 'get_chat_info': {
                        const disabledResponse = checkToolEnabled('get_chat_info');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = request.params;

                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        const { chatId } = args;

                        if (!chatId) {
                            return { status: 'E22-R-2200', message: 'chatId ist erforderlich, um Chat-Informationen abzurufen.' };
                        }

                        try {
                            const response = await this.axiosInstance.get(`/chats/${chatId}`, {
                                headers: { Authorization: `Bearer ${token}` }
                            });

                            const chatData = response.data?.data;

                            if (!chatData) {
                                return {
                                    status: 'E22-R-2201',
                                    message: t.noChatData,
                                };
                            }

                            return {
                                data: {
                                    chatId: chatData.chatId,
                                    title: chatData.title || 'Unbenannter Chat',
                                    language: chatData.language || 'Unbekannt',
                                    groups: chatData.groups || [],
                                    messages: chatData.messages || []
                                },
                                message: response.data?.message || 'Erfolgreich abgerufen.'
                            };
                        } catch (error) {
                            const fetchChatErrorMessage = error.message || error.response?.data;
                            console.error(t.fetchChatInfoError.replace('${error}', fetchChatErrorMessage));
                            return {
                                status: 'E22-R-2202',
                                message: error.response?.data?.message || 'Fehler beim Abrufen der Chat-Informationen.'
                            };
                        }
                    }
                /*  3.0 Create Source ##############################################################################*/
                    case 'create_source': {
                        const disabledResponse = checkToolEnabled('create_source');
                        if (disabledResponse) return disabledResponse;

                        const args = request.params.arguments;
                        const token = request.params.token;

                        // Validierung: Erforderliche Parameter prüfen
                        if (!token) {
                            return { status: 'E30-R-3000', message: t.missingTokenError };
                        }
                        if (!args || !args.name || !args.content) {
                            return { status: 'E30-R-3001', message: t.missingParametersError.replace('${parameters}', 'name und content') };
                        }

                        const { name, content, groups } = args;

                        try {
                            // Token im Header setzen
                            this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;

                            // Gruppenvalidierung vorab durchführen
                            if (groups && groups.length > 0) {
                                console.log('📤 Überprüfen der Gruppen:', groups);

                                const response = await this.axiosInstance.get('/groups');
                                const availableGroups = response.data?.data?.assignableGroups || [];

                                // Ungültige Gruppen ermitteln
                                const invalidGroups = groups.filter(group => !availableGroups.includes(group));
                                if (invalidGroups.length > 0) {
                                    console.error('❌ Ungültige Gruppen gefunden:', invalidGroups);
                                    return {
                                        status: 'E30-R-3002',
                                        message: `Ungültige Gruppen: ${invalidGroups.join(', ')}`,
                                    };
                                }
                            }

                            // API-Aufruf zur Erstellung der Quelle
                            const createSourceResponse = await this.axiosInstance.post(
                                '/sources',
                                { name, content, groups },
                                { headers: { Authorization: `Bearer ${token}` } }
                            );

                            console.log('✔️ Quelle erfolgreich erstellt:', createSourceResponse.data);

                            // Erfolgsantwort
                            return {
                                status: createSourceResponse.data?.status || 'ok',
                                message: createSourceResponse.data?.message || 'Quelle erfolgreich erstellt.',
                                data: createSourceResponse.data?.data,
                            };
                        } catch (error) {
                            const createSourceError = error.response?.data || error.message;
                            console.error(t.createSourceError.replace('${error}', createSourceError));

                            // console.error('❌ Fehler beim Erstellen der Quelle:', error.response?.data || error.message);

                            // Fehlerhafte Antwort
                            if (error.response) {
                                return {
                                    status: 'E30-R-3003',
                                    message: error.response.data?.message || 'Ein Fehler ist aufgetreten.',
                                    details: {
                                        status: error.response.status,
                                        headers: error.response.headers,
                                        data: error.response.data,
                                    },
                                };
                            } else if (error.request) {
                                return {
                                    status: 'E30-R-3004',
                                    message: t.noServerResponse,
                                    details: { request: error.request },
                                };
                            } else {
                                return {
                                    status: 'E30-R-3005',
                                    message: error.message || 'Ein unbekannter Fehler ist aufgetreten.',
                                };
                            }
                        }
                    }
                /*  3.1 Get Source #################################################################################*/
                    case 'get_source': {
                        const disabledResponse = checkToolEnabled('get_source');
                        if (disabledResponse) return disabledResponse;
                        const args = request.params.arguments;
                        console.log(t.makingGetSourceRequest.replace('${args}', JSON.stringify(args, null, 2)));
                        const getSourceResponse = await this.axiosInstance.get(`/sources/${args.sourceId}`);
                        console.log(t.gotGetSourceResponse.replace('${data}', JSON.stringify(getSourceResponse.data, null, 2)));
                        return {
                            content: [
                                {
                                    type: 'text',
                                    text: JSON.stringify(getSourceResponse.data, null, 2)
                                }
                            ]
                        };
                    }
                /*  3.2 List Sources ###############################################################################*/  
                    case 'list_sources': {
                        const disabledResponse = checkToolEnabled('list_sources');
                        if (disabledResponse) return disabledResponse;
                        const args = request.params.arguments;
                        console.log(t.makingListSourcesRequest.replace('${args}', JSON.stringify(args, null, 2)));
                        const listSourcesResponse = await this.axiosInstance.post('/sources/groups', {
                            groupName: args.groupName
                        });
                        console.log(t.gotListSourcesResponse.replace('${data}', JSON.stringify(listSourcesResponse.data, null, 2)));
                        return {
                            content: [
                                {
                                    type: 'text',
                                    text: JSON.stringify(listSourcesResponse.data, null, 2)
                                }
                            ]
                        };
                    }
                /*  3.3 Edit Source ################################################################################*/  
                    case 'edit_source': {
                        const disabledResponse = checkToolEnabled('edit_source');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = request.params;

                        // Validierung: Token erforderlich
                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        const { sourceId, title, content, groups } = args;

                        // Validierung: Pflichtfeld `sourceId`
                        if (!sourceId) {
                            return {
                                data: {},
                                message: t.missingParameterError.replace('${parameter}', 'sourceId'),
                                status: 'E33-R-3300', // Bad Request
                            };
                        }

                        console.log(`Bearbeite Quelle mit ID: ${sourceId}, Titel: ${title || 'unverändert'}`);

                        try {
                            // Payload dynamisch erstellen
                            const payload = {};
                            if (title) payload.title = title;
                            if (content) payload.content = content;
                            if (groups) payload.groups = groups;

                            // API-Aufruf: Quelle bearbeiten
                            const editSourceResponse = await this.axiosInstance.patch(
                                `/sources/${sourceId}`,
                                payload,
                                {
                                    headers: {
                                        Authorization: `Bearer ${token}`, // Nutze den bereitgestellten Token
                                    },
                                }
                            );

                            console.log(t.editSourceSuccess.replace('${data}', JSON.stringify(editSourceResponse.data, null, 2)));

                            // Erfolgreiche Antwort
                            return {
                                data: editSourceResponse.data?.data || {}, // Optionale Daten aus der API
                                message: editSourceResponse.data?.message || 'Quelle erfolgreich bearbeitet.',
                                status: editSourceResponse.status || 200, // OK
                            };
                        } catch (error) {
                            const editSourceError = error.message || JSON.stringify(error.response?.data);
                            console.error(t.editSourceError.replace('${error}', editSourceError));

                            // console.error(`❌ Fehler beim Bearbeiten der Quelle: ${error.message || JSON.stringify(error.response?.data)}`);

                            // Fehlerhafte Antwort
                            return {
                                data: {},
                                message: error.response?.data?.message || 'Bearbeiten der Quelle fehlgeschlagen. Bitte versuchen Sie es später erneut.',
                                status: error.response?.status || 'E33-R-3301', // Internal Server Error
                            };
                        }
                    }
                /*  3.4 Delete Source ##############################################################################*/
                    case 'delete_source': {
                        const disabledResponse = checkToolEnabled('delete_source');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = request.params.arguments;

                        // Validierung: Token erforderlich
                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        const { sourceId } = args;

                        // Validierung: sourceId erforderlich
                        if (!sourceId) {
                            return {
                                data: {},
                                message: t.missingParameterError.replace('${parameter}', 'sourceId'),
                                status: 'E34-R-3400', // Bad Request
                            };
                        }

                        try {
                            // API-Aufruf: Quelle löschen
                            const deleteResponse = await this.axiosInstance.delete(`/sources/${sourceId}`, {
                                headers: { Authorization: `Bearer ${token}` },
                            });

                            console.log(`Quelle erfolgreich gelöscht: ${JSON.stringify(deleteResponse.data, null, 2)}`);

                            // Erfolgreiche Antwort
                            return {
                                data: deleteResponse.data?.data || {}, // Optionale Daten aus der API
                                message: deleteResponse.data?.message || 'Quelle erfolgreich gelöscht.',
                                status: deleteResponse.status || 200, // OK
                            };
                        } catch (error) {
                            // console.error(`❌ Fehler beim Löschen der Quelle: ${error.message || JSON.stringify(error.response?.data)}`);
                            const deleteSourceError = error.message || JSON.stringify(error.response?.data);
                            console.error(t.deleteSourceError.replace('${error}', deleteSourceError));


                            // Fehlerhafte Antwort
                            return {
                                data: {},
                                message: error.response?.data?.message || 'Löschen der Quelle fehlgeschlagen. Bitte versuchen Sie es später erneut.',
                                status: error.response?.status || 'E34-R-3401', // Internal Server Error
                            };
                        }
                    }
                /*  4.0 List Groups ################################################################################*/
                    case 'list_groups': {
                        const disabledResponse = checkToolEnabled('list_groups');
                        if (disabledResponse) return disabledResponse;
                        console.log(t.makingListGroupsRequest);
                        const listGroupsResponse = await this.axiosInstance.get('/groups');
                        console.log(t.gotListGroupsResponse, listGroupsResponse.data);
                        return {
                            content: [
                                {
                                    type: 'text',
                                    text: JSON.stringify(listGroupsResponse.data, null, 2)
                                }
                            ]
                        };
                    }
                /*  4.1 Store Group ################################################################################*/
                    case 'store_group': {
                        const disabledResponse = checkToolEnabled('store_group');
                        if (disabledResponse) return disabledResponse;
                        const args = request.params.arguments;

                        if (!args || !args.groupName) {
                            throw new McpError(ErrorCode.InvalidRequest, 'Store: Fehlender erforderlicher Parameter: groupName.');
                        }

                        console.log(
                            t.storeGroupLog
                                .replace('${groupName}', args.groupName)
                                .replace('${description}', args.description || 'Keine Beschreibung angegeben')
                        );

                        // console.log(`Storing new group with name: ${args.groupName} and description: ${args.description || 'No description provided'}`);

                        try {
                            const storeGroupResponse = await this.axiosInstance.post('/groups', {
                                groupName: args.groupName,
                                description: args.description || ''
                            });
                            console.log(
                                t.storeGroupSuccess.replace('${data}', JSON.stringify(storeGroupResponse.data, null, 2))
                            );
                            // console.log(`Group stored successfully: ${JSON.stringify(storeGroupResponse.data, null, 2)}`);

                            return {
                                content: [
                                    {
                                        type: 'text',
                                        text: `Group "${args.groupName}" successfully stored with ID: ${storeGroupResponse.data.id}`
                                    }
                                ]
                            };
                        } catch (error) {
                            console.error(t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)));
                            if (axios.isAxiosError(error)) {
                                const message = error.response?.data?.message ?? error.message;
                                console.error(
                                    t.apiErrorDetails.replace('${status}', error.response?.status || 'E41-R-4100').replace('${data}', JSON.stringify(error.response?.data || {}, null, 2))
                                );
                                return {
                                    content: [
                                        {
                                            type: 'text',
                                            text: `API error: ${message}`
                                        }
                                    ],
                                    isError: true
                                };
                            }
                            throw error;
                        }
                    };
                /*  4.2 Delete Group ###############################################################################*/  
                    case 'delete_group': {
                        const disabledResponse = checkToolEnabled('delete_group');
                        if (disabledResponse) return disabledResponse;
                        
                        const { groupName } = request.params.arguments; // Extrahiere die Gruppe
                        if (!groupName) {
                            throw new McpError(ErrorCode.InvalidRequest, 'Delete Fehlender erforderlicher Parameter: groupName.');
                        }

                        // console.log(`Lösche Gruppe mit Name: ${groupName}`);
                        console.log(t.deleteGroupLog.replace('${groupName}', groupName));


                        try {
                            // API-Aufruf mit dem notwendigen JSON-Body
                            const deleteGroupResponse = await this.axiosInstance.delete('/groups', {
                                data: { groupName }, // JSON-Body für den DELETE-Request
                            });

                            // console.log(t.deleteGroupSuccessLog.replace('${data}', JSON.stringify(deleteGroupResponse.data)));
                            console.log(t.deleteGroupSuccessLog.replace('${data}', JSON.stringify(deleteGroupResponse.data)));


                            return {
                                content: [
                                    {
                                        type: 'text',
                                        text: `Gruppe "${groupName}" wurde erfolgreich gelöscht.`,
                                    },
                                ],
                            };
                        } catch (error) {
                            // console.error(`Fehler bei der API-Anfrage: ${error.message || JSON.stringify(error.response?.data)}`);
                            const apiError = error.message || JSON.stringify(error.response?.data);
                            console.error(t.apiRequestError.replace('${error}', apiError));
                            if (axios.isAxiosError(error)) {
                                const message = error.response?.data?.message || 'Fehler beim Löschen der Gruppe.';
                                return {
                                    content: [
                                        {
                                            type: 'text',
                                            text: `API-Fehler: ${message}`,
                                        },
                                    ],
                                    isError: true,
                                };
                            }
                            throw new McpError(ErrorCode.InternalError, 'Interner Fehler beim Löschen der Gruppe.');
                        }
                    }           
                /*  5.0 Store User #################################################################################*/
                    case 'store_user': {
                        const disabledResponse = checkToolEnabled('store_user');
                        if (disabledResponse) return disabledResponse;

                        // Token und Argumente aus request.params entnehmen
                        const { token, arguments: args } = request.params;

                        // Token validieren
                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        // Erforderliche Felder prüfen
                        if (!args || !args.name || !args.email || !args.password) {
                            return {
                                status: 'E50-R-5000',
                                message: 'Fehlende erforderliche Felder: name, email oder password.'
                            };
                        }

                        try {
                            // Benutzer anlegen
                            const response = await this.axiosInstance.post(
                                '/users',
                                {
                                    name: args.name,
                                    email: args.email,
                                    password: args.password,
                                    language: args.language || 'en',
                                    timezone: args.timezone || 'Europe/Berlin',
                                    roles: args.roles || [],
                                    groups: args.groups || [],
                                    usePublic: args.usePublic || false
                                },
                                {
                                    headers: {
                                        Authorization: `Bearer ${token}`
                                    }
                                }
                            );

                            // Erfolgreiche Antwort
                            return {
                                status: response.data?.status || 'ok',
                                message: response.data?.message || 'Benutzer erfolgreich erstellt.',
                                data: response.data?.data
                            };
                        } catch (error) {
                            // console.error('❌ Fehler beim Erstellen des Benutzers:', error.response?.data || error.message);
                            const createUserError = error.response?.data || error.message;
                            console.error(t.createUserError.replace('${error}', createUserError));
                            return {
                                status: error.response?.status || 'E50-R-5001',
                                message: error.response?.data?.message || 'Fehler beim Erstellen des Benutzers.'
                            };
                        }
                    }
                /*  5.1 Edit User ##################################################################################*/
                    case 'edit_user': {
                        const disabledResponse = checkToolEnabled('edit_user');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = request.params;
                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        // Mindestens die E-Mail muss angegeben sein, um den User zu identifizieren
                        if (!args || !args.email) {
                            return {
                                status: 'E51-R-5100',
                                message: 'Die E-Mail des Benutzers ist erforderlich, um den Datensatz zu bearbeiten.'
                            };
                        }

                        try {
                            // Nur Felder senden, die tatsächlich aktualisiert werden sollen
                            const payload = {};
                            if (args.name) payload.name = args.name;
                            if (args.password) payload.password = args.password;
                            if (args.language) payload.language = args.language;
                            if (args.timezone) payload.timezone = args.timezone;
                            if (Array.isArray(args.roles)) payload.roles = args.roles;
                            if (Array.isArray(args.groups)) payload.groups = args.groups;
                            if (typeof args.usePublic === 'boolean') payload.usePublic = args.usePublic;

                            // E-Mail ist Pflicht, um den Benutzer auf dem Server zu finden
                            payload.email = args.email;

                            const response = await this.axiosInstance.patch(
                                '/users',
                                payload,
                                {
                                    headers: { Authorization: `Bearer ${token}` }
                                }
                            );

                            return {
                                status: response.data?.status || 'ok',
                                message: response.data?.message || 'Benutzer erfolgreich bearbeitet.',
                                data: response.data?.data
                            };
                        } catch (error) {
                            const editUserError = error.response?.data || error.message;
                            console.error(t.editUserError.replace('${error}', editUserError));
                            // console.error('❌ Fehler beim Bearbeiten des Benutzers:', error.response?.data || error.message);
                            return {
                                status: error.response?.status || 'E51-R-5101',
                                message: error.response?.data?.message || 'Fehler beim Bearbeiten des Benutzers.'
                            };
                        }
                    }
                /*  5.2 Delete User ################################################################################*/
                    case 'delete_user': {
                        const disabledResponse = checkToolEnabled('delete_user');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = request.params;
                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        // E-Mail ist nötig, um den Benutzer zu löschen
                        if (!args || !args.email) {
                            return {
                                status: 'E52-R-5200',
                                message: 'Die E-Mail ist erforderlich, um einen Benutzer zu löschen.'
                            };
                        }

                        try {
                            // DELETE-Anfrage mit JSON-Body
                            const response = await this.axiosInstance.delete(
                                '/users',
                                {
                                    data: { email: args.email },
                                    headers: { Authorization: `Bearer ${token}` }
                                }
                            );

                            return {
                                status: response.data?.status || 'ok',
                                message: response.data?.message || 'Benutzer erfolgreich gelöscht.',
                                data: response.data?.data
                            };
                        } catch (error) {
                            // console.error('❌ Fehler beim Löschen des Benutzers:', error.response?.data || error.message);
                            const deleteUserError = error.response?.data || error.message;
                            console.error(t.deleteUserError.replace('${error}', deleteUserError));
                            return {
                                status: error.response?.status || 'E52-R-5201',
                                message: error.response?.data?.message || 'Fehler beim Löschen des Benutzers.'
                            };
                        }
                    }               
                    default:
                        throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
                }
            }
            catch (error) {
                console.error(t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)));
                if (axios.isAxiosError(error)) {
                    const message = error.response?.data?.message ?? error.message;
                    console.error(t.apiErrorDetails.replace('${status}', error.response?.status || 'Unknown').replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)));
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `API error: ${message}`
                            }
                        ],
                        isError: true
                    };
                }
                throw error;
            }
        });
    }
    
/* ##################################################################################################
   # MESSAGE HANDLER
   ##################################################################################################*/
    async run() {
        const isPortInUse = (port) => new Promise((resolve, reject) => {
            const tester = net.createServer()
                .once('error', (err) => (err.code === 'EADDRINUSE' ? resolve(true) : reject(err)))
                .once('listening', () => tester.once('close', () => resolve(false)).close())
                .listen(port);
        });

        const PORT = Port;
        if (await isPortInUse(PORT)) {
            throw new Error(t.portInUse.replace('${PORT}', PORT));
        }

        const transport = new TcpServerTransport(PORT);
        await transport.start(async (message) => {
            try {
                console.log(t.incomingMessage, message);

                 // Token-Validierung nur durchführen, wenn es nicht der "login"-Befehl ist
                //if (message.command !== 'login') {
                    // const tokenValidation = validateToken(message.token);
                    // if (tokenValidation) return tokenValidation;
                // }
                
                if (!message || typeof message !== 'object') {
                    throw new McpError(ErrorCode.InvalidRequest, 'Ungültige Nachricht oder leere Anfrage.');
                }

                // Verarbeite verschiedene Anfragen dynamisch
                if (!message.command) {
                    throw new McpError(ErrorCode.InvalidRequest, 'Fehlender Befehlsparameter in der Nachricht.');
                }
                switch (message.command) {
                /*  1.0 Login ######################################################################################*/
                    case 'login': {
                        const disabledResponse = checkToolEnabled('login');
                        if (disabledResponse) return disabledResponse;

                        // Extrahiere die Argumente aus der Nachricht
                        const args = getArguments(message);
                        const { email, password: Pwd } = args;

                        // Überprüfe, ob die E-Mail und das Passwort vorhanden sind
                        if (!email || !Pwd) {
                            return {
                                status: 'E10-M-1050',
                                message: 'E-Mail und Passwort sind erforderlich.',
                            };
                        }

                        let password;

                        // Passwort entschlüsseln, falls erforderlich
                        if (typeof PwEncryption !== 'undefined' && PwEncryption) {
                            password = decryptPassword(Pwd);
                        } else {
                            password = Pwd;
                        }         
                        
                        try {
                            // Login-API aufrufen
                            const loginResponse = await this.axiosInstance.post('/login', { email, password });

                            console.log(t.loginSuccess.replace('${data}', JSON.stringify(loginResponse.data)));

                            // Token zurückgeben
                            return {
                                status: loginResponse.data?.status || 'ok', // Dynamisch, falls der API-Status einheitlich ist
                                message: loginResponse.data?.message || 'Login erfolgreich.', // API-Nachricht verwenden oder Standardnachricht
                                token: loginResponse.data?.data?.token, // Token aus API-Antwort
                            };
                        } catch (error) {
                            const errorMessage = error.response?.data || error.message;
                            console.error(t.loginError.replace('${error}', errorMessage));
                            // console.error('❌ Fehler beim Login:', error.response?.data || error.message);

                            return {
                                status: error.response?.status || 'E10-M-1051', // API-Fehlerstatus oder Standardfehlerstatus,
                                message: error.response?.data || error.message || 'no error message'
                            };
                        }
                    }
                /*  1.1 Logout #####################################################################################*/  
                    case 'logout': {
                        const disabledResponse = checkToolEnabled('logout');
                        if (disabledResponse) return disabledResponse;
                        
                        const { token } = message;

                        try {
                            const logoutResponse = await this.axiosInstance.delete('/logout', {
                                headers: {
                                    Authorization: `Bearer ${token}`
                                }
                            });

                            console.log(t.logoutSuccess.replace('${data}', JSON.stringify(logoutResponse.data)));
                            // console.log('✔️ Logout erfolgreich:', logoutResponse.data);

                             return {
                                data: {}, // Optional: Zusätzliche Daten könnten hier eingefügt werden
                                status: logoutResponse.data?.status || 'no status', // Dynamisch, falls der API-Status einheitlich ist
                                message: logoutResponse.data?.message || 'no message', // API-Nachricht verwenden oder Standardnachricht
                            };
                        } catch (error) {
                                const logoutErrorMessage = error.response?.data || error.message;
                                console.error(t.logoutError.replace('${error}', logoutErrorMessage));
                            // console.error('❌ Fehler beim Logout:', error.response?.data || error.message);
                            return {
                                data: {},
                                message: error.response?.data || error.message || 'no error message',
                                status: error.response?.status || 'E11-M-1150', // Internal Server Error oder spezifischer Statuscode
                            };
                        }
                    }
                /*  2.0 Chat #######################################################################################*/  
                    case 'chat': {
                        const disabledResponse = checkToolEnabled('chat');
                        if (disabledResponse) return disabledResponse;
                        
                        // Extrahiere den Token und die Argumente
                        const token = message.token; // Token direkt extrahieren
                        const args = message.arguments || {}; // Sichere Extraktion der Argumente
                        const { question, usePublic, groups, language } = args;
                        
                        //const { token, arguments: args } = message;
//                      const { token, question, usePublic, groups, language } = args;
                        
                        // Argument-Validierung
                        if (!args || !args.question) {
                            return {
                                status: 'E20-M-2050',
                                message: 'Fehlende Frage in den Argumenten.',
                            };
                        }
                        
                        console.log('message Extrahierter Token:', token);

                        //const { question, usePublic, groups, language } = args;

                        // Konflikt zwischen `usePublic` und `groups` lösen
                        if (usePublic && groups && groups.length > 0) {
                            console.warn("⚠️ Konflikt: usePublic wurde auf false gesetzt, da Gruppen angegeben sind.");
                            args.usePublic = false;
                        }

                        try {
                            // API-Aufruf zur Verarbeitung der Chat-Anfrage
                            const response = await this.axiosInstance.post(
                                '/chats',
                                {
                                    question,
                                    usePublic: usePublic || false,
                                    // groups: Array.isArray(groups) ? groups : [groups],
                                    groups: Array.isArray(groups) ? groups : groups ? [groups] : [],
                                    language: language || 'de',
                                },
                                {
                                    headers: { Authorization: `Bearer ${token}` },
                                }
                            );

                            const data = response.data?.data || {};
                            console.log(t.chatResponseSuccess.replace('${data}', JSON.stringify(data)));
                          
                            // Erfolgsantwort mit Status und Daten
                            return {
                                status: response.data?.status || 'ok',
                                message: response.data?.message || 'Chat erfolgreich.',
                                content: {
                                    chatId: data.chatId,
                                    answer: data.answer,
                                    sources: data.sources || [],
                                },
                            };
                        } catch (error) {
                            const chatApiErrorMessage = error.message || error.response?.data;
                            console.error(t.chatApiError.replace('${error}', chatApiErrorMessage));

                            // Fehlerantwort mit Status und Nachricht
                            return {
                                status: error.response?.data?.status || error.message.status || 'E20-M-2051',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
                        }
                    }
                /*  2.1 Continue Chat ##############################################################################*/
                    case 'continue_chat': {
                        const disabledResponse = checkToolEnabled('continue_chat');
                        if (disabledResponse) return disabledResponse;
                        //const { token, arguments: args } = message;
                        //const { token, chatId, question } = args;
                        const token = message.token; // Token direkt extrahieren
                        const args = message.arguments || {}; // Sichere Extraktion der Argumente

                        //const { token } = message;
                        //const args = message.arguments || {};
                        const { chatId, question } = args;
                        

                        if (!args || !args.chatId || !args.question) {
                            return { status: 'E21-M-2150', message: 'Fehlende erforderliche Parameter: chatId und/oder question.' };
                        }

                        //const { chatId, question } = args;

                        try {
                            const continueChatResponse = await this.axiosInstance.patch(
                                `/chats/${chatId}`,
                                { question },
                                { headers: { Authorization: `Bearer ${token}` } }
                            );
                            console.log(t.conversationSuccess.replace('${data}', JSON.stringify(continueChatResponse.data, null, 2)));
                            return {
                                content: {
                                    chatId:  continueChatResponse.data.data.chatId,
                                    answer:  continueChatResponse.data.data.answer,
                                    sources: continueChatResponse.data.sources || [],
                                    message: continueChatResponse.data.message,
                                    status:  continueChatResponse.data.status,
                                },
                            };
                        } catch (error) {
                            //console.error(`Fehler bei der API-Anfrage: ${error.message}`);
                            console.error(t.apiRequestError.replace('${error}', error.message));
                            return {
                                status: 'E21-M-2151',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
                        }
                    }
                /*  2.2 Get Chat Info ##############################################################################*/  
                    case 'get_chat_info': {
                        const disabledResponse = checkToolEnabled('get_chat_info');
                        if (disabledResponse) return disabledResponse;
                        
                        //const { token, chatId } = args;
                        
                        //const { token, arguments: args } = message;

                        //const { chatId } = args;
                        const { token } = message; // Token direkt aus `message` extrahieren
                        const args = message.arguments || {}; // Argumente aus `message` extrahieren
                        const { chatId } = args; // chatId aus den Argumenten extrahieren


                        if (!chatId) {
                            return { status: 'E22-M-2250', message: 'chatId ist erforderlich, um Chat-Informationen abzurufen.' };
                        }

                        try {
                            const response = await this.axiosInstance.get(`/chats/${chatId}`, {
                                headers: { Authorization: `Bearer ${token}` }
                            });

                            const chatData = response.data?.data;

                            if (!chatData) {
                                return {
                                    status: 'E22-M-2251',
                                    message: t.noChatData,
                                };
                            }

                            // Formatiertes Ergebnis zurückgeben
                            return {
                                data: {
                                    chatId: chatData.chatId,
                                    title: chatData.title || 'Unbenannter Chat',
                                    language: chatData.language || 'Unbekannt',
                                    groups: chatData.groups || [],
                                    messages: chatData.messages || []
                                },
                                message: response.data?.message || 'Erfolgreich abgerufen.'
                            };
                        } catch (error) {
                            const fetchChatErrorMessage = error.message || error.response?.data;
                            console.error(t.fetchChatInfoError.replace('${error}', fetchChatErrorMessage));
                            return {
                                status: 'E22-M-2252',
                                message: error.response?.data?.message || error.message || 'no error message'
                            };
                        }
                    }
                /*  3.0 Create Source ##############################################################################*/  
                    case 'create_source': {
                        const disabledResponse = checkToolEnabled('create_source');
                        if (disabledResponse) return disabledResponse;

                        const args = getArguments(message);
                        // const args = request.params.arguments;
                        const token = message.token;

                        // Validierung: Erforderliche Parameter prüfen
                        if (!token) {
                            return { status: 'E30-M-3050', message: t.missingTokenError };
                        }
                        if (!args || !args.name || !args.content) {
                            return { status: 'E30-M-3051', message: t.missingParametersError.replace('${parameters}', 'name und content') };
                        }

                        const { name, content, groups } = args;

                        try {
                            // Gruppenvalidierung vorab durchführen
                            if (groups && groups.length > 0) {
                                const groupValidation = await this.validateGroups(groups, token);
                                if (!groupValidation.isValid) {
                                    return {
                                        status: 'E30-M-3052',
                                        message: t.invalidGroupsError.replace('${invalidGroups}', groupValidation.invalidGroups.join(', '))
                                    };
                                }
                            }

                            // API-Aufruf zur Erstellung der Quelle
                            const createSourceResponse = await this.axiosInstance.post(
                                '/sources',
                                { name, content, groups },
                                { headers: { Authorization: `Bearer ${token}` } }
                            );

                            console.log('✔️ Quelle erfolgreich erstellt:', createSourceResponse.data);

                            // Erfolgsantwort
                            return {
                                status: createSourceResponse.data?.status || 'ok',
                                message: createSourceResponse.data?.message || 'Quelle erfolgreich erstellt.',
                                data: createSourceResponse.data?.data,
                            };
                        } catch (error) {
                            // console.error('❌ Fehler beim Erstellen der Quelle:', error.response?.data || error.message);
                            const createSourceError = error.response?.data || error.message;
                            console.error(t.createSourceError.replace('${error}', createSourceError));

                            // Fehlerhafte Antwort
                            if (error.response) {
                                return {
                                    status: 'E30-M-3053',
                                    message: error.response?.data?.message || error.message || 'no error message',
                                    details: {
                                        status: error.response.status,
                                        headers: error.response.headers,
                                        data: error.response.data,
                                    },
                                };
                            } else if (error.request) {
                                return {
                                    status: 'E30-M-3054',
                                    message: t.noServerResponse,
                                    details: { request: error.request },
                                };
                            } else {
                                return {
                                    status: 'E30-M-3055',
                                    message: error.message || 'Ein unbekannter Fehler ist aufgetreten.',
                                };
                            }
                        }
                    }
                /*  3.1 Get Source #################################################################################*/              
                    case 'get_source': {
                        const disabledResponse = checkToolEnabled('get_source');
                        if (disabledResponse) return disabledResponse;
                        const { token, arguments: args } = message; // Extrahiere den Token und die Argumente
                        //const { token, sourceId } = args;
                        const { sourceId } = args; // Extrahiere sourceId aus den Argumenten

                        if (!sourceId) {
                            return { status: 'E31-M-3150', message: t.groupNameRequired.replace('${param}', 'sourceId') };
                        }

                        console.log(t.makingGetSourceRequest.replace('${sourceId}', sourceId));

                        try {
                            const sourceResponse = await this.axiosInstance.get(`/sources/${sourceId}`, {
                                headers: {
                                    Authorization: `Bearer ${token}`, // Nutze den vom Client bereitgestellten Token
                                },
                            });

                            console.log(t.gotGetSourceResponse.replace('${data}', JSON.stringify(sourceResponse.data, null, 2)));

                            return {
                                content: sourceResponse.data,
                            };
                        } catch (error) {
                            console.error(t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)));
                            return {
                                status: 'E31-M-3151',
                                message: t.apiErrorDetails
                                    .replace('${status}', error.response?.status || 'E31-M-3151')
                                    .replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)),
                            };
                        }
                    }
                /*  3.2 List Sources ###############################################################################*/      
                    case 'list_sources': {
                        const disabledResponse = checkToolEnabled('list_sources');
                        if (disabledResponse) return disabledResponse;
                        const { token, attributes } = message; // Extrahiere den Token und die Attribute

                        //const { token, groupName } = args;
                        if (!attributes || !attributes.groupName) {
                            return { status: 'E32-M-3250', message: 'Gruppenname erforderlich für diese Anfrage.' };
                        }

                        const groupName = attributes.groupName; // Extrahiere den groupName aus attributes
                        console.log(t.fetchingSources.replace('${groupName}', groupName));

                        try {
                            // Führe die API-Anfrage aus, um die Quellen für die Gruppe zu erhalten
                            const sourceResponse = await this.axiosInstance.post(
                                '/sources/groups',
                                { groupName },
                                {
                                    headers: {
                                        Authorization: `Bearer ${token}`, // Nutze den vom Client bereitgestellten Token
                                    },
                                }
                            );

                            console.log(t.sourcesRetrieved.replace('${data}', JSON.stringify(sourceResponse.data, null, 2)));

                            return {
                                content: sourceResponse.data, // Sende die Antwort zurück
                            };
                        } catch (error) {
                            console.error(t.groupValidationError.replace('${error}', error.message || JSON.stringify(error)));
                            return {
                                status: 'E32-M-3251',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
//                              status: 'error',
                                //message: t.groupFetchError,
                        }
                    }
                /*  3.3 Edit Source ################################################################################*/              
                    case 'edit_source': {
                        const disabledResponse = checkToolEnabled('edit_source');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = message;

                        const { sourceId, title, content, groups } = args;

                        // Validierung: Erforderliche Parameter
                        if (!sourceId) {
                            return {
                                data: {},
                                message: t.missingParameterError.replace('${parameter}', 'sourceId'),
                                status: 'E33-M-3350', // Bad Request
                            };
                        }

                        // console.log(`Bearbeite Quelle mit ID: ${sourceId}, Titel: ${title || 'unverändert'}`);
                        console.log(
                            t.editSourceLog
                                .replace('${sourceId}', sourceId)
                                .replace('${title}', title || 'unverändert')
                        );

                        try {
                            // API-Aufruf: Quelle bearbeiten
                            const payload = {};
                            if (title) payload.title = title;
                            if (content) payload.content = content;
                            if (groups) payload.groups = groups;

                            const editSourceResponse = await this.axiosInstance.patch(
                                `/sources/${sourceId}`,
                                payload,
                                {
                                    headers: {
                                        Authorization: `Bearer ${token}`, // Nutze den bereitgestellten Token
                                    },
                                }
                            );

                            console.log(t.editSourceSuccess.replace('${data}', JSON.stringify(editSourceResponse.data, null, 2)));

                            // Erfolgreiche Antwort
                            return {
                                data: editSourceResponse.data?.data || {}, // Optionale Daten aus der API
                                message: editSourceResponse.data?.message || 'Quelle erfolgreich bearbeitet.',
                                status: editSourceResponse.status || 200, // OK
                            };
                        } catch (error) {
                            const editSourceError = error.message || JSON.stringify(error.response?.data);
                            console.error(t.editSourceError.replace('${error}', editSourceError));

                            // console.error(`❌ Fehler beim Bearbeiten der Quelle: ${error.message || JSON.stringify(error.response?.data)}`);

                            // Fehlerhafte Antwort
                            return {
                                data: {},
                                message: error.response?.data?.message || 'Bearbeiten der Quelle fehlgeschlagen. Bitte versuchen Sie es später erneut.',
                                status: error.response?.status || 'E33-M-3351', // Internal Server Error
                            };
                        }
                    }
                /*  3.4 Delete Source ##############################################################################*/  
                    case 'delete_source': {
                        const disabledResponse = checkToolEnabled('delete_source');
                        if (disabledResponse) return disabledResponse;

                        const { token, arguments: args } = message;
                        const { sourceId } = args;

                        if (!sourceId) {
                            return { status: 'E34-M-3450', message: t.groupNameRequired.replace('${param}', 'sourceId') };
                        }

                        try {
                            const deleteResponse = await this.axiosInstance.delete(`/sources/${sourceId}`, {
                                headers: { Authorization: `Bearer ${token}` },
                            });

                            console.log(`Quelle erfolgreich gelöscht: ${JSON.stringify(deleteResponse.data, null, 2)}`);

                            return {
                                content: deleteResponse.data,
                            };
                        } catch (error) {
                            console.error(t.errorHandlingRequest.replace('${error}', error.message || JSON.stringify(error, null, 2)));
                            return {
                                status: 'E34-M-3451',
                                message: t.apiErrorDetails
                                    .replace('${status}', error.response?.status || 'E34-M-3451')
                                    .replace('${data}', JSON.stringify(error.response?.data || {}, null, 2)),
                            };
                        }
                    }       
                /*  4.0 List Groups ################################################################################*/  
                    case 'list_groups': {
                        const disabledResponse = checkToolEnabled('list_groups');
                        if (disabledResponse) return disabledResponse;
                        //const token = message.arguments?.token || message.token;
                        const token = message.token; // Token direkt aus `message` extrahieren
                        
                        try {
                            await this.ensureAuthenticated(token);

                            const response = await this.axiosInstance.get('/groups');
                            let assignableGroups = response.data?.data?.assignableGroups || [];
                            const personalGroups = response.data?.data?.personalGroups || [];
                            const message = response.data?.message || 'no_message'; // Fallback für Nachricht
                            const status = response.data?.status || 'E40-M-4050'; // Fallback für Status

                            
                            if (isRestrictedGroupsEnabled) {
                                // console.log('⚠️ RESTRICTED_GROUPS aktiviert. Verfügbare Gruppen werden eingeschränkt.');
                                console.log(t.restrictedGroupsWarning);
                                assignableGroups = ["NO ACCESS ALLOWED BY THE MCP-SERVER CONFIG"]; // Alle assignableGroups entfernen
                            }

                            return {
                                data: {
                                    personalGroups,
                                    assignableGroups,
                                    message,
                                    status,
                                },
                            };
                        } catch (error) {
                            const fetchGroupsError = error.message || JSON.stringify(error.response?.data);
                            console.error(t.fetchGroupsError.replace('${error}', fetchGroupsError));


                            // Detaillierte Fehlerbehandlung
                            if (axios.isAxiosError(error)) {
                                const status = error.response?.status;
                                const serverMessage = error.response?.data?.message || error.message || 'no error message';
                                return {
                                    status: 'E40-M-4051',
                                    message: `Fehler beim Abrufen der Gruppen: ${serverMessage} (Status: ${status})`,
                                };
                            }

                            return {
                                status: 'E40-M-4052',
                                message: 'Ein unbekannter Fehler ist aufgetreten.',
                            };
                        }
                    }       
                /*  4.1 Store Group ################################################################################*/  
                    case 'store_group': {
                        const disabledResponse = checkToolEnabled('store_group');
                        if (disabledResponse) return disabledResponse;
                        
                        //const { groupName, description } = args; // Einheitliche Extraktion über getArguments
                        const { groupName, description } = message.arguments; // Extrahiere die Argumente
                        const clientToken = message.token; // Token aus der Anfrage

                        if (!groupName || !description) {
                            return { status: 'E41-M-4150', message: 'Fehlende erforderliche Parameter: groupName und description.' };
                        }

                        if (!clientToken) {
                            return { status: 'E41-M-4151', message: t.missingTokenError };
                        }

                        try {
                            // API-Aufruf mit dem vom Client bereitgestellten Token
                            const createGroupResponse = await this.axiosInstance.post(
                                '/groups',
                                { groupName, description },
                                {
                                    headers: {
                                        Authorization: `Bearer ${clientToken}` // Nutze nur den Client-Token
                                    }
                                }
                            );

                            console.log(t.createGroupSuccess.replace('${data}', JSON.stringify(createGroupResponse.data)));

                            return {
                                content: createGroupResponse.data,
                            };
                        } catch (error) {
                            // console.error('❌ Fehler bei der API-Anfrage:', error.response?.data || error.message);
                            const apiError = error.response?.data || error.message;
                            console.error(t.apiRequestError.replace('${error}', apiError));
                            return {
                                status: 'E41-M-4152',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
                        }
                    }
                /*  4.2 Delete Group ###############################################################################*/  
                    case 'delete_group': {
                        const disabledResponse = checkToolEnabled('delete_group');
                        if (disabledResponse) return disabledResponse;
                        
                        //const { token, groupName } = args;
                        
                        const { token, arguments: args } = message; // Extrahiere Token und Argumente
                        const { groupName } = args;

                        if (!groupName) {
                            return { status: 'E42-M-4250', message: 'Fehlender erforderlicher Parameter: groupName.' };
                        }

                        // console.log(`Lösche Gruppe mit Name: ${groupName}`);
                        console.log(t.deleteGroupLog.replace('${groupName}', groupName));


                        try {
                            // API-Aufruf mit dem Token des Clients
                            const deleteGroupResponse = await this.axiosInstance.delete('/groups', {
                                data: { groupName }, // JSON-Body für DELETE-Request
                                headers: {
                                    Authorization: `Bearer ${token}`, // Nutze den vom Client bereitgestellten Token
                                },
                            });

                            console.log(t.deleteGroupSuccessLog.replace('${data}', JSON.stringify(deleteGroupResponse.data)));
                    
                            return {
                                data: deleteGroupResponse.data?.data || {},
                                message: deleteGroupResponse.data?.message || 'success',
                                status: deleteGroupResponse.status || 200,
                            };
                        } catch (error) {
                            // console.error(`❌ Fehler beim Löschen der Quelle: ${error.message || JSON.stringify(error.response?.data)}`);
                            const deleteSourceError = error.message || JSON.stringify(error.response?.data);
                            console.error(t.deleteSourceError.replace('${error}', deleteSourceError));
    

                            // Fehlerhafte Antwort
                            return {
                                data: {},
                                message: error.response?.data?.message || error.message || 'no error message',
                                status: error.response?.status || 'E42-M-4251', // Internal Server Error oder spezifischer Statuscode
                            };
                        }
                    }               
                /*  5.0 Store User #################################################################################*/              
                    case 'store_user': {
                        const disabledResponse = checkToolEnabled('store_user');
                        if (disabledResponse) return disabledResponse;
                        const { token, arguments: args } = message;

                        //const { token, name, email, password } = args;
                        
                        if (!args || !args.name || !args.email || !args.password) {
                            return { status: 'E50-M-5050', message: 'Fehlende erforderliche Parameter: name, email oder password.' };
                        }


                        // Extrahiere die Argumente aus der Nachricht
                        //const args = getArguments(message);
                        const Pwd = args.password;

                        // Überprüfe, ob die E-Mail und das Passwort vorhanden sind
                        if (!Pwd) {
                            return {
                                status: 'E10-M-1050',
                                message: 'Passwort ist erforderlich.',
                            };
                        }

                        let password;

                        // Passwort entschlüsseln, falls erforderlich
                        if (typeof PwEncryption !== 'undefined' && PwEncryption) {
                            password = decryptPassword(Pwd);
                        } else {
                            password = Pwd;
                        }        


                        try {
                            // Payload für die API-Anfrage
                            const payload = {
                                name: args.name,
                                email: args.email,
                                language: args.language || 'en',
                                timezone: args.timezone || 'Europe/Berlin',
                                password: password,
                                usePublic: args.usePublic || false,
                                groups: args.groups || [],
                                roles: args.roles || [],
                                activateFtp: args.activateFtp || false,
                                ftpPassword: args.ftpPassword || '',
                            };

                            console.log(t.createUserLog.replace('${payload}', JSON.stringify(payload)));

                            // API-Aufruf
                            const createUserResponse = await this.axiosInstance.post('/users', payload, {
                                headers: {
                                    Authorization: `Bearer ${token}`
                                }
                            });

                            console.log(t.createUserSuccess.replace('${data}', JSON.stringify(createUserResponse.data)));

                            return {
                                content: createUserResponse.data,
                            };
                        } catch (error) {
                            const createUserError = error.response?.data || error.message;
                            console.error(t.createUserError.replace('${error}', createUserError));

                            // console.error('❌ Fehler beim Erstellen des Benutzers:', error.response?.data || error.message);

                            const errors = error.response?.data?.errors;
                            if (errors) {
                                const errorMessages = [];
                                for (const [key, messages] of Object.entries(errors)) {
                                    messages.forEach(message => errorMessages.push(`${key}: ${message}`));
                                }

                                return {
                                    status: 'E50-M-5051',
                                    message: 'Fehler beim Erstellen des Benutzers:',
                                    errors: errorMessages
                                };
                            }

                            return {
                                status: 'E50-M-5052',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
                        }
                    }
                /*  5.1 Edit User ##################################################################################*/
                    case 'edit_user': {
                        const disabledResponse = checkToolEnabled('edit_user');
                        if (disabledResponse) return disabledResponse;
                        
                        const { token, arguments: args } = message;
                        const tokenValidation = validateToken(token);
                        if (tokenValidation) return tokenValidation;

                        // Mindestens die E-Mail muss angegeben sein, um den User zu identifizieren
                        if (!args || !args.email) {
                            return {
                                status: 'E51-R-5100',
                                message: 'Die E-Mail des Benutzers ist erforderlich, um den Datensatz zu bearbeiten.'
                            };
                        }

                        let password = null;

                        if (args.password) {
                            const Pwd = args.password;
                            if (!Pwd) {
                                return {
                                    status: 'E51-M-1050',
                                    message: 'Passwort ist erforderlich.',
                                };
                            }
                            if (typeof PwEncryption !== 'undefined' && PwEncryption) {
                                password = decryptPassword(Pwd);
                            } else {
                                password = Pwd;
                            } 
                        }

                        try {
                            // Nur Felder senden, die tatsächlich aktualisiert werden sollen
                            const payload = {};
                            if (args.name) payload.name = args.name;
                            if (args.password) payload.password = password;
                            if (args.language) payload.language = args.language;
                            if (args.timezone) payload.timezone = args.timezone;
                            if (Array.isArray(args.roles)) payload.roles = args.roles;
                            if (Array.isArray(args.groups)) payload.groups = args.groups;
                            if (typeof args.usePublic === 'boolean') payload.usePublic = args.usePublic;

                            // E-Mail ist Pflicht, um den Benutzer auf dem Server zu finden
                            payload.email = args.email;
                            const response = await this.axiosInstance.patch(
                                '/users',
                                payload,
                                {
                                    headers: { Authorization: `Bearer ${token}` }
                                }
                            );
                            console.log(t.editUserSuccess.replace('${data}', JSON.stringify(response.data)));

                            return {
                                status: response.data?.status || 'ok',
                                message: response.data?.message || 'Benutzer erfolgreich bearbeitet.',
                                data: response.data?.data
                            };
                        } catch (error) {
                            const editUserError = error.response?.data || error.message;
                            console.error(t.editUserError.replace('${error}', editUserError));
                            // console.error('❌ Fehler beim Bearbeiten des Benutzers:', error.response?.data || error.message);
                            return {
                                status: error.response?.status || 'E51-M-5151',
                                message: error.response?.data?.message || 'Fehler beim Bearbeiten des Benutzers.'
                            };
                        }
/*
                        const { token, arguments: args } = message;

                        //const { token, email, ...updates } = args;
                        const { email, ...updates } = args;

                        if (!email) {
                            return { status: 'E51-M-5150', message: 'Email ist erforderlich, um einen Benutzer zu bearbeiten.' };
                        }

                        try {
                            const response = await this.axiosInstance.patch(
                                '/users',
                                { email, ...updates },
                                { headers: { Authorization: `Bearer ${token}` } }
                            );

                            console.log(t.editUserSuccess.replace('${data}', JSON.stringify(response.data)));

                            return {
                                content: response.data,
                            };
                        } catch (error) {
                            const editUserError = error.response?.data || error.message;
                            console.error(t.editUserError.replace('${error}', editUserError));
                            // console.error('❌ Fehler beim Bearbeiten des Benutzers:', error.response?.data || error.message);
                            return {
                                status: 'E51-M-5151',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
                        }*/
                    }
                /*  5.2 Delete User ################################################################################*/  
                    case 'delete_user': {
                        const disabledResponse = checkToolEnabled('delete_user');
                        if (disabledResponse) return disabledResponse;
                        const { token, arguments: args } = message;

                        const { email } = args;
                        //const { token, email } = args;

                        if (!email) {
                            return { status: 'E52-M-5250', message: 'Email ist erforderlich, um einen Benutzer zu löschen.' };
                        }

                        try {
                            const response = await this.axiosInstance.delete(
                                '/users',
                                {
                                    data: { email },
                                    headers: { Authorization: `Bearer ${token}` }
                                }
                            );

                           console.log(t.deleteUserSuccess.replace('${data}', JSON.stringify(response.data)));

                            return {
                                content: response.data,
                            };
                        } catch (error) {
                            const deleteUserError = error.response?.data || error.message;
                            console.error(t.deleteUserError.replace('${error}', deleteUserError));
                            // console.error('❌ Fehler beim Löschen des Benutzers:', error.response?.data || error.message);
                            return {
                                status: 'E52-M-5251',
                                message: error.response?.data?.message || error.message || 'no error message',
                            };
                        }
                    }
                /*  9.0 Generate Key ###############################################################################*/    
                    case 'keygen': {
                        const disabledResponse = checkToolEnabled('keygen');
                        if (disabledResponse) return disabledResponse;

                        const { password } = message.arguments;

                        try {
                            // Passwort verschlüsseln
                            const encryptedPassword = getEncryptedKey(password);

                            // Schlüssel zurückgeben
                            return {
                                data: {
                                    key: encryptedPassword
                                },
                                status: 'ok',
                                message: 'Keygen erfolgreich.',
                            };
                        } catch (error) {
                            console.error('❌ Fehler bei der Keygen-Anfrage:', error.message);
                            return {
                                data: {},
                                message: error.message || 'Keygen fehlgeschlagen.',
                                status: 'E90-M-1150',
                            };
                        }
                    }
                }
            } catch (err) {
                console.error(t.tcpServerError, err.message || err);
                return { status: 'E52-M-5252', message: err.message || t.internalServerError };
            }
        });
    }
}
const server = new PrivateGPTServer();
// Server läuft
console.log(
    messages[lang].serverRunning
        .replace('${port}', PORT)
);
server.run().catch(console.error);
```
Page 14/16FirstPrevNextLast