#
tokens: 49905/50000 25/501 files (page 8/16)
lines: off (toggle) GitHub
raw markdown copy
This is page 8 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

--------------------------------------------------------------------------------
/clients/PHP/1.0 mcp_login/MCPLoginClient.php:
--------------------------------------------------------------------------------

```php
<?php
// Functions for parsing command line arguments
function parseArguments($args) {
    $parsedArgs = [];
    $argc = count($args);
    for ($i = 1; $i < $argc; $i++) {
        switch ($args[$i]) {
            case '--server-ip':
                if (isset($args[$i + 1])) {
                    $parsedArgs['serverIp'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --server-ip expects a value.\n");
                    exit(1);
                }
                break;
            case '--server-port':
                if (isset($args[$i + 1])) {
                    $parsedArgs['serverPort'] = intval($args[++$i]);
                } else {
                    fwrite(STDERR, "Error: --server-port expects a value.\n");
                    exit(1);
                }
                break;
            case '--email':
                if (isset($args[$i + 1])) {
                    $parsedArgs['email'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --email expects a value.\n");
                    exit(1);
                }
                break;
            case '--password':
                if (isset($args[$i + 1])) {
                    $parsedArgs['password'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --password expects a value.\n");
                    exit(1);
                }
                break;
            default:
                fwrite(STDERR, "Warning: Unknown argument: {$args[$i]}\n");
        }
    }
    return $parsedArgs;
}

// Function for sending a request over a TCP connection
function sendRequest($serverIp, $serverPort, $payload) {
    $jsonPayload = json_encode($payload);
    if ($jsonPayload === false) {
        throw new Exception("Error encoding JSON payload.");
    }

    $errno = 0;
    $errstr = '';
    $timeout = 30; // seconds
    $client = fsockopen($serverIp, $serverPort, $errno, $errstr, $timeout);
    
    if (!$client) {
        throw new Exception("Connection error: $errstr ($errno)");
    }

    echo "🔗 Connection to server established.\n";

    fwrite($client, $jsonPayload);

    $responseData = '';
    stream_set_timeout($client, $timeout);

    while (!feof($client)) {
        $data = fread($client, 1024);
        if ($data === false) {
            throw new Exception("Error reading data from server.");
        }
        $responseData .= $data;

        // Attempt to parse the received data as JSON
        $parsedData = json_decode($responseData, true);
        if ($parsedData !== null) {
            fclose($client);
            return $parsedData;
        }

        // Check if the stream timed out
        $info = stream_get_meta_data($client);
        if ($info['timed_out']) {
            throw new Exception("Timeout waiting for data from server.");
        }
    }

    fclose($client);
    throw new Exception("Connection to the server was closed before a complete response was received.");
}

// Function for interactively asking for a password (optional)
function askPassword($prompt) {
    if (preg_match('/^win/i', PHP_OS)) {
        // Windows-specific password prompt
        $vbscript = sys_get_temp_dir() . 'prompt_password.vbs';
        file_put_contents($vbscript, 'wscript.echo(InputBox("' . addslashes($prompt) . '", "", "password here"))');
        $password = shell_exec("cscript //nologo " . escapeshellarg($vbscript));
        unlink($vbscript);
        return trim($password);
    } else {
        // Unix/Linux password prompt
        echo $prompt;
        system('stty -echo');
        $password = rtrim(fgets(STDIN), "\n");
        system('stty echo');
        echo "\n";
        return $password;
    }
}

// Main function
function main($argv) {
    $args = parseArguments($argv);
    $serverIp = $args['serverIp'] ?? null;
    $serverPort = $args['serverPort'] ?? null;
    $email = $args['email'] ?? null;
    $password = $args['password'] ?? null;

    // Check if all required parameters are present
    if (!$serverIp || !$serverPort || !$email || !$password) {
        fwrite(STDERR, "❌ ERROR: Missing required parameters.\n");
        fwrite(STDOUT, "Usage: php MCPLoginClient.php --server-ip <IP> --server-port <Port> --email <Email> --password <Password>\n");
        exit(1);
    }

    $payload = [
        "command" => "login",
        "arguments" => [
            "email" => $email,
            "password" => $password
        ]
    ];

    try {
        echo "🔐 Logging in...\n";
        $response = sendRequest($serverIp, $serverPort, $payload);
        echo "✅ Server Response:\n";
        echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    } catch (Exception $e) {
        fwrite(STDERR, "❌ ERROR: " . $e->getMessage() . "\n");
    }
}

main($argv);
?>

```

--------------------------------------------------------------------------------
/clients/PHP/1.1 mcp_logout/MCPLogoutClient.php:
--------------------------------------------------------------------------------

```php
<?php
// Functions for parsing command line arguments
function parseArguments($args) {
    $parsedArgs = [];
    $argc = count($args);
    for ($i = 1; $i < $argc; $i++) {
        switch ($args[$i]) {
            case '--server-ip':
                if (isset($args[$i + 1])) {
                    $parsedArgs['serverIp'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --server-ip expects a value.\n");
                    exit(1);
                }
                break;
            case '--server-port':
                if (isset($args[$i + 1])) {
                    $parsedArgs['serverPort'] = intval($args[++$i]);
                } else {
                    fwrite(STDERR, "Error: --server-port expects a value.\n");
                    exit(1);
                }
                break;
            case '--token':
                if (isset($args[$i + 1])) {
                    $parsedArgs['token'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --token expects a value.\n");
                    exit(1);
                }
                break;
            default:
                fwrite(STDERR, "Warning: Unknown argument: {$args[$i]}\n");
        }
    }
    return $parsedArgs;
}

// Function for interactively asking for a token (optional)
function askToken($prompt) {
    if (preg_match('/^win/i', PHP_OS)) {
        // Windows-specific token prompt
        $vbscript = sys_get_temp_dir() . 'prompt_token.vbs';
        file_put_contents($vbscript, 'wscript.echo(InputBox("' . addslashes($prompt) . '", "", "token here"))');
        $token = shell_exec("cscript //nologo " . escapeshellarg($vbscript));
        unlink($vbscript);
        return trim($token);
    } else {
        // Unix/Linux token prompt
        echo $prompt;
        // Token input typically without echo
        if (shell_exec('which stty')) {
            system('stty -echo');
            $token = rtrim(fgets(STDIN), "\n");
            system('stty echo');
            echo "\n";
            return $token;
        } else {
            // Fallback if stty is unavailable
            return rtrim(fgets(STDIN), "\n");
        }
    }
}

// Function for sending a logout request over a TCP connection
function sendLogoutRequest($serverIp, $serverPort, $payload) {
    $jsonPayload = json_encode($payload);
    if ($jsonPayload === false) {
        throw new Exception("Error encoding JSON payload.");
    }

    $errno = 0;
    $errstr = '';
    $timeout = 30; // seconds
    $client = fsockopen($serverIp, $serverPort, $errno, $errstr, $timeout);
    
    if (!$client) {
        throw new Exception("Connection error: $errstr ($errno)");
    }

    echo "🔗 Connection to server established.\n";

    fwrite($client, $jsonPayload);

    $responseData = '';
    stream_set_timeout($client, $timeout);

    while (!feof($client)) {
        $data = fread($client, 1024);
        if ($data === false) {
            throw new Exception("Error reading data from server.");
        }
        $responseData .= $data;

        // Attempt to parse the received data as JSON
        $parsedData = json_decode($responseData, true);
        if ($parsedData !== null) {
            fclose($client);
            return $parsedData;
        }

        // Check if the stream timed out
        $info = stream_get_meta_data($client);
        if ($info['timed_out']) {
            throw new Exception("Timeout waiting for data from server.");
        }
    }

    fclose($client);
    throw new Exception("Connection to the server was closed before a complete response was received.");
}

// Main function
function main($argv) {
    $args = parseArguments($argv);
    $serverIp = $args['serverIp'] ?? null;
    $serverPort = $args['serverPort'] ?? null;
    $token = $args['token'] ?? null;

    // Check if all required parameters except token are present
    if (!$serverIp || !$serverPort) {
        fwrite(STDERR, "❌ ERROR: Missing required parameters.\n");
        fwrite(STDOUT, "Usage: php MCPLogoutClient.php --server-ip <IP> --server-port <Port> --token <Token>\n");
        exit(1);
    }

    // Interactively ask for token if not provided in arguments
    $authToken = $token;
    if (!$authToken) {
        $authToken = askToken('🔒 Please enter your authentication token: ');
    }

    if (empty($authToken)) {
        fwrite(STDERR, "❌ ERROR: Authentication token must not be empty.\n");
        exit(1);
    }

    $payload = [
        "command" => "logout",
        "token" => $authToken
    ];

    try {
        echo "🚪 Logging out...\n";
        $response = sendLogoutRequest($serverIp, $serverPort, $payload);
        echo "✅ Server Response:\n";
        echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    } catch (Exception $e) {
        fwrite(STDERR, "❌ ERROR: " . $e->getMessage() . "\n");
    }
}

main($argv);
?>

```

--------------------------------------------------------------------------------
/clients/C++/5.0 mcp_store_user/MCPStoreUserClient.cpp:
--------------------------------------------------------------------------------

```cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <sstream>
#include <stdexcept>
#include <json/json.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib") // Verlinkung mit der Winsock-Bibliothek

// Funktion zum Parsen von Argumenten
std::map<std::string, std::string> parseArguments(int argc, char* argv[]) {
    std::map<std::string, std::string> args;
    for (int i = 1; i < argc; ++i) {
        std::string key = argv[i];
        if (i + 1 < argc && key.rfind("--", 0) == 0) {
            args[key] = argv[++i];
        }
    }
    return args;
}

// Funktion zum Parsen von Listen-Argumenten
std::vector<std::string> parseListArgument(int argc, char* argv[], const std::string& key) {
    std::vector<std::string> values;
    for (int i = 1; i < argc; ++i) {
        if (argv[i] == key && i + 1 < argc) {
            for (int j = i + 1; j < argc && std::string(argv[j]).rfind("--", 0) != 0; ++j) {
                values.push_back(argv[j]);
            }
        }
    }
    return values;
}

// Funktion zum Senden der Anfrage
std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) {
    Json::StreamWriterBuilder writer;
    std::string payloadJson = Json::writeString(writer, payload);

    // Winsock initialisieren
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        throw std::runtime_error("Failed to initialize Winsock.");
    }

    // Socket erstellen
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        WSACleanup();
        throw std::runtime_error("Failed to create socket.");
    }

    // Server-Adresse konfigurieren
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) {
        closesocket(sock);
        WSACleanup();
        throw std::runtime_error("Invalid server IP address.");
    }

    // Verbindung herstellen
    if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        closesocket(sock);
        WSACleanup();
        throw std::runtime_error("Connection failed.");
    }

    // Daten senden
    if (send(sock, payloadJson.c_str(), payloadJson.size(), 0) < 0) {
        closesocket(sock);
        WSACleanup();
        throw std::runtime_error("Failed to send data.");
    }

    // Antwort empfangen
    char buffer[4096];
    int bytesRead;
    std::ostringstream response;

    do {
        bytesRead = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (bytesRead > 0) {
            buffer[bytesRead] = '\0'; // Null-terminieren
            response << buffer;
        }
    } while (bytesRead == sizeof(buffer) - 1);

    // Socket schließen
    closesocket(sock);
    WSACleanup();

    return response.str();
}

int main(int argc, char* argv[]) {
    try {
        auto args = parseArguments(argc, argv);

        // Argumente auslesen
        std::string serverIp = args["--server-ip"];
        int serverPort = std::stoi(args["--server-port"]);
        std::string token = args["--token"];
        std::string name = args["--name"];
        std::string email = args["--email"];
        std::string password = args["--password"];
        std::string language = args.count("--language") ? args["--language"] : "en";
        std::string timezone = args.count("--timezone") ? args["--timezone"] : "Europe/Berlin";
        auto roles = parseListArgument(argc, argv, "--roles");
        auto groups = parseListArgument(argc, argv, "--groups");
        bool usePublic = args.count("--usePublic");
        bool activateFtp = args.count("--activateFtp");
        std::string ftpPassword = args.count("--ftpPassword") ? args["--ftpPassword"] : "";

        // JSON-Payload erstellen
        Json::Value payload;
        payload["command"] = "store_user";
        payload["token"] = token;
        payload["arguments"]["name"] = name;
        payload["arguments"]["email"] = email;
        payload["arguments"]["password"] = password;
        payload["arguments"]["language"] = language;
        payload["arguments"]["timezone"] = timezone;
        for (const auto& role : roles) {
            payload["arguments"]["roles"].append(role);
        }
        for (const auto& group : groups) {
            payload["arguments"]["groups"].append(group);
        }
        payload["arguments"]["usePublic"] = usePublic;
        payload["arguments"]["activateFtp"] = activateFtp;
        payload["arguments"]["ftpPassword"] = ftpPassword;

        std::cout << "📤 Sending store user request...\n";

        // Anfrage senden und Antwort erhalten
        std::string response = sendRequest(serverIp, serverPort, payload);

        std::cout << "✔️ Response from server:\n" << response << "\n";
    } catch (const std::exception& e) {
        std::cerr << "❌ ERROR: " << e.what() << "\n";
        return 1;
    }

    return 0;
}

```

--------------------------------------------------------------------------------
/agents/IoTAgent/Python/language.py:
--------------------------------------------------------------------------------

```python
# language.py
languages = {
    "en": {
        "configuration_loaded": "Configuration loaded from {config_path}.",
        "error_loading_config": "Error loading configuration: {e}",
        "welcome": "Connected to MQTT broker successfully.",
        "chatbot_error_status": "Chatbot returned error status {status_code}.",
        "start_uploading_file": "Starting upload for file: {file_path}.",
        "error_sftp_upload": "Error uploading file {file_path}: {e}",
        "file_archived": "File {file_path} archived as {archive_name}.",
        "error_archiving_file": "Error archiving file {file_path}: {e}",
        "file_size": "File {file_path} size: {file_size} bytes.",
        "file_limit_reached": "File {file_path} reached size limit of {size_limit} bytes.",
        "new_file_created": "New file created at {file_path}.",
        "cannot_create_new_file": "Cannot create new file of type {file_type} for language {language}.",
        "error_getting_suffixes": "Error getting suffixes: {e}",
        "record_added": "Record added to {file_path}.",
        "invalid_group": "Invalid group type: {groups}.",
        "error_writing_file": "Error writing to file {file_path}: {e}",
        "file_empty_or_corrupted": "File {file_path} is empty or corrupted.",
        "language_sentence_generated": "Language: {language_full} | Sentence: {sentence}",
        "no_translation_file_config": "No translation file configured for language {language}.",
        "no_file_handler_found": "No file handler found for language {language}.",
        "no_translation_file_in_config": "No translation file configured in config for language {language}.",
        "empty_answer_field": "Warning: 'answer' field is empty in the chatbot response.",
        "max_retries_reached": "Maximum retry attempts reached.",
        "communication_error": "Communication error: {e} | Attempt {attempt} of {max_retries}.",
        "waiting_before_retry": "Waiting {wait_seconds} seconds before retrying...",
        "error_in_interpret_and_output": "Error in interpret_and_output: {e}",
        "sending_request_to_chatbot": "Sending request to chatbot (Attempt {attempt}).",
        "chatbot_response": "Chatbot response: {response}",
        "unknown_language": "Unknown language: {language}.",
        "no_sentence_generated": "No sentence generated for language {language_full}.",
        "user_exit": "User initiated exit."
    },
    "de": {
        "configuration_loaded": "Konfiguration geladen von {config_path}.",
        "error_loading_config": "Fehler beim Laden der Konfiguration: {e}",
        "welcome": "Erfolgreich mit dem MQTT-Broker verbunden.",
        "chatbot_error_status": "Chatbot hat Fehlerstatus {status_code} zurückgegeben.",
        "start_uploading_file": "Starte Upload für Datei: {file_path}.",
        "error_sftp_upload": "Fehler beim Hochladen der Datei {file_path}: {e}",
        "file_archived": "Datei {file_path} archiviert als {archive_name}.",
        "error_archiving_file": "Fehler beim Archivieren der Datei {file_path}: {e}",
        "file_size": "Datei {file_path} Größe: {file_size} Bytes.",
        "file_limit_reached": "Datei {file_path} hat das Größenlimit von {size_limit} Bytes erreicht.",
        "new_file_created": "Neue Datei erstellt unter {file_path}.",
        "cannot_create_new_file": "Kann keine neue Datei vom Typ {file_type} für Sprache {language} erstellen.",
        "error_getting_suffixes": "Fehler beim Abrufen der Suffixe: {e}",
        "record_added": "Datensatz hinzugefügt zu {file_path}.",
        "invalid_group": "Ungültiger Gruppentyp: {groups}.",
        "error_writing_file": "Fehler beim Schreiben in die Datei {file_path}: {e}",
        "file_empty_or_corrupted": "Datei {file_path} ist leer oder beschädigt.",
        "language_sentence_generated": "Sprache: {language_full} | Satz: {sentence}",
        "no_translation_file_config": "Keine Übersetzungsdatei für Sprache {language} konfiguriert.",
        "no_file_handler_found": "Kein Dateihandler für Sprache {language} gefunden.",
        "no_translation_file_in_config": "Keine Übersetzungsdatei in der Konfiguration für Sprache {language} konfiguriert.",
        "empty_answer_field": "Warnung: 'answer'-Feld ist in der Chatbot-Antwort leer.",
        "max_retries_reached": "Maximale Anzahl an Wiederholungsversuchen erreicht.",
        "communication_error": "Kommunikationsfehler: {e} | Versuch {attempt} von {max_retries}.",
        "waiting_before_retry": "Warte {wait_seconds} Sekunden bevor erneut versucht wird...",
        "error_in_interpret_and_output": "Fehler in interpret_and_output: {e}",
        "sending_request_to_chatbot": "Sende Anfrage an Chatbot (Versuch {attempt}).",
        "chatbot_response": "Chatbot-Antwort: {response}",
        "unknown_language": "Unbekannte Sprache: {language}.",
        "no_sentence_generated": "Kein Satz für Sprache {language_full} generiert.",
        "user_exit": "Benutzer hat die Anwendung beendet."
    }
}

```

--------------------------------------------------------------------------------
/clients/Java/3.0 mcp_create_source/MCPCreateSourceClient.java:
--------------------------------------------------------------------------------

```java
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class MCPCreateSourceClient {

    public static void main(String[] args) {
        // Entspricht dem Minimalcheck (8 Parameter) wie im C#-Code.
        if (args.length < 8) {
            printUsage();
            return;
        }

        String serverIp  = getArgument(args, "--server-ip");
        String portStr   = getArgument(args, "--server-port");
        String token     = getArgument(args, "--token");
        String name      = getArgument(args, "--name");
        String content   = getArgument(args, "--content");
        List<String> groups = getArgumentList(args, "--groups");

        // Falls wichtige Argumente fehlen, direkt Usage anzeigen
        if (serverIp == null || portStr == null || token == null 
            || name == null || content == null) {
            printUsage();
            return;
        }

        int serverPort = Integer.parseInt(portStr);

        System.out.println("📤 Sending request to create a new source...");

        // JSON-Payload erstellen
        JSONObject payload = new JSONObject();
        payload.put("command", "create_source");
        payload.put("token", token);

        // "arguments" Objekt
        JSONObject arguments = new JSONObject();
        arguments.put("name", name);
        arguments.put("content", content);

        // "groups" als JSONArray hinzufügen
        JSONArray groupsJsonArray = new JSONArray(groups);
        arguments.put("groups", groupsJsonArray);

        payload.put("arguments", arguments);

        // Request an den MCP-Server senden
        String response = sendRequest(serverIp, serverPort, payload);
        System.out.println("✔️ Response from server:");
        System.out.println(response);
    }

    /**
     * Gibt einen einzelnen Argumentwert für das gegebene Schlüsselwort zurück,
     * oder null, wenn keiner gefunden wurde.
     */
    private static String getArgument(String[] args, String key) {
        for (int i = 0; i < args.length - 1; i++) {
            if (args[i].equals(key)) {
                return args[i + 1];
            }
        }
        return null;
    }

    /**
     * Sucht im args-Array nach dem Schlüssel 'key' und liest dann solange
     * weiter, bis das nächste Argument wieder mit "--" beginnt (oder das Array endet).
     * So können mehrere Gruppenwerte nacheinander gelesen werden.
     */
    private static List<String> getArgumentList(String[] args, String key) {
        List<String> values = new ArrayList<>();
        for (int i = 0; i < args.length; i++) {
            if (args[i].equals(key)) {
                // Ab hier die folgenden Einträge sammeln, bis "--" oder Ende
                for (int j = i + 1; j < args.length; j++) {
                    if (args[j].startsWith("--")) {
                        break;
                    }
                    values.add(args[j]);
                }
                break; // Suche beenden, sobald wir die Liste gefunden haben
            }
        }
        return values;
    }

    /**
     * Baut eine Socket-Verbindung zum Server auf, sendet das JSON-Payload
     * und empfängt die Antwort.
     */
    private static String sendRequest(String serverIp, int serverPort, JSONObject payload) {
        String payloadJson = payload.toString();

        try (Socket client = new Socket(serverIp, serverPort)) {
            // Daten senden
            OutputStream out = client.getOutputStream();
            byte[] data = payloadJson.getBytes(StandardCharsets.UTF_8);
            out.write(data);
            out.flush();

            // Antwort empfangen
            InputStream in = client.getInputStream();
            byte[] buffer = new byte[4096];
            StringBuilder responseBuilder = new StringBuilder();
            int bytesRead;

            do {
                bytesRead = in.read(buffer);
                if (bytesRead > 0) {
                    responseBuilder.append(new String(buffer, 0, bytesRead, StandardCharsets.UTF_8));
                }
            } while (bytesRead == buffer.length);

            return responseBuilder.toString();

        } catch (IOException e) {
            return "Error: " + e.getMessage();
        }
    }

    private static void printUsage() {
        System.out.println("Usage:");
        System.out.println("  --server-ip <IP> --server-port <PORT> --token <TOKEN> "
                         + "--name <NAME> --content <CONTENT> [--groups <GROUP1 GROUP2 ...>]");
        System.out.println();
        System.out.println("Example:");
        System.out.println("  java -cp .;json-20241224.jar MCPCreateSourceClient "
                         + "--server-ip 127.0.0.1 --server-port 1234 --token MyToken "
                         + "--name \"Test Source\" --content \"This is some content\" "
                         + "--groups dev hr admin");
    }
}

```

--------------------------------------------------------------------------------
/WORKLOG.md:
--------------------------------------------------------------------------------

```markdown
# PrivateGPT MCP Server Development Log

## ⚠️ Warning: User Management Implementation

**HANDLE WITH CARE**: The user management endpoints have significant impact and can potentially delete all users if not handled properly. While the API functionality has been tested successfully, implementation in the pgpt-mcp-server is pending due to these security considerations.

The following user management endpoints require careful implementation:

### Create User (POST /api/v1/users)
Required functionality:
- Create new user with name, email, and password
- Set optional language and timezone
- Configure public access and group assignments
- Assign user roles
- Set up FTP access if needed
- Handle all required fields:
  ```json
  {
    "name": "User Name",
    "email": "[email protected]",
    "password": "UserPassword123",
    "language": "en",
    "timezone": "UTC",
    "usePublic": true,
    "groups": ["Group A"],
    "roles": ["Sources"],
    "activateFtp": true,
    "ftpPassword": "FTPPassword!"
  }
  ```

### Edit User (PATCH /api/v1/users)
Required functionality:
- Update user details by email
- Modify name, language, and group assignments
- Handle partial updates
- Fields that can be updated:
  ```json
  {
    "email": "[email protected]",
    "name": "Updated Name",
    "language": "en",
    "groups": ["Updated Group"]
  }
  ```

### Delete User (DELETE /api/v1/users)
⚠️ **Critical Operation**
Required functionality:
- Remove user by email
- Clean up associated data
- Handle dependencies:
  ```json
  {
    "email": "[email protected]"
  }
  ```

## Implementation Status

### Core Server Structure
- ✅ Basic MCP server setup with stdio transport
- ✅ Error handling and graceful shutdown
- ✅ Type-safe request handling
- ✅ Input validation for all tools

### API Integration
- ✅ Authentication with Bearer tokens
- ✅ Automatic token refresh
- ✅ Error mapping to MCP error codes
- ✅ JSON response formatting

### Tools Implementation
1. Chat Tool
   - ✅ Chat creation with knowledge base selection
   - ✅ Support for public and document knowledge bases
   - ✅ Group-based access control
   - ✅ Language support
   - ✅ Chat continuation support

2. Source Management
   - ✅ Source creation with markdown formatting
   - ✅ Group assignment for private sources
   - ✅ Source listing by group
   - ✅ Source details retrieval
   - ✅ Source deletion
   - ✅ Source editing

3. Group Management
   - ✅ List personal and assignable groups
   - ✅ Group-based visibility control
   - ✅ Personal group handling
   - ✅ Group creation
   - ✅ Group deletion

## API Behavior Notes

### Authentication
- Uses Bearer token authentication via `/api/v1/login`
- Token required for all authenticated endpoints
- Token invalidation via `/api/v1/logout`

### Group Management
- GET `/api/v1/groups` returns personalGroups and assignableGroups arrays
- Personal group appears in both arrays
- Groups control access to sources and knowledge base
- Full CRUD operations implemented and tested

### Source Management
- Sources can be public or private
- Private sources require group assignment
- Sources are vectorized asynchronously
- Source states: creation → vectorized
- Source operations:
  - POST `/api/v1/sources` for creation
  - DELETE `/api/v1/sources/{sourceId}` for removal
  - PATCH `/api/v1/sources/{sourceId}` for editing
  - Can list sources by group
  - Can verify source state and visibility
- All operations tested and verified

### Chat System
- Two knowledge base types:
  - Public (usePublic: true)
  - Document (specific groups)
- Chat operations:
  - Initial creation: POST `/api/v1/chats`
  - Continuation: PATCH `/api/v1/chats/{chatId}`
  - Details: GET `/api/v1/chats/{chatId}`
- Chat features:
  - Preserves complete message history
  - Context-aware responses
  - Group-based access control
  - Language support

## Implementation Details

### Type Safety
- Comprehensive TypeScript interfaces for all API interactions
- Runtime validation for all tool inputs
- Error type mapping between API and MCP

### Error Handling
- API errors mapped to appropriate MCP error codes
- Detailed error messages preserved
- Authentication errors handled gracefully

### Resource Management
- No direct resource exposure currently
- All data access through tools
- Future potential for direct resource access

## Future Improvements
1. Performance Optimizations:
   - Add caching layer
   - Optimize API requests
   - Improve response times

2. Monitoring and Observability:
   - Add comprehensive logging
   - Add metrics collection
   - Add performance tracking

3. Documentation:
   - Add API reference documentation
   - Add deployment guides
   - Add troubleshooting guides

4. Security Enhancements:
   - Add rate limiting
   - Implement request validation
   - Add security headers
   - Enhance token management
   - Add user session management

## Testing Notes
- ✅ All major API endpoints tested
- ✅ Group-based access control verified
- ✅ Chat system behavior documented
- ✅ Source visibility rules confirmed
- ✅ Error handling validated
- ✅ Source CRUD operations verified
- ✅ Group CRUD operations verified
- ✅ User management API functionality tested

```

--------------------------------------------------------------------------------
/clients/C++/1.0 mcp_login/MCPLoginClient.cpp:
--------------------------------------------------------------------------------

```cpp
#include <iostream>
#include <string>
#include <map>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <stdexcept>
#include <json/json.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libssl.lib")
#pragma comment(lib, "libcrypto.lib")
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif

// Function to parse command-line arguments
std::map<std::string, std::string> parseArguments(int argc, char* argv[]) {
    std::map<std::string, std::string> args;
    for (int i = 1; i < argc; i++) {
        std::string key = argv[i];
        if (i + 1 < argc) {
            args[key] = argv[++i];
        }
    }
    return args;
}

void init_openssl() {
    SSL_load_error_strings();   
    OpenSSL_add_ssl_algorithms();
}

void cleanup_openssl() {
    EVP_cleanup();
}

SSL_CTX* create_context() {
    const SSL_METHOD* method;
    SSL_CTX* ctx;

    method = TLS_client_method();
    ctx = SSL_CTX_new(method);
    if (!ctx) {
        perror("Unable to create SSL context");
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    return ctx;
}

std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) {
    init_openssl();
    SSL_CTX* ctx = create_context();

#ifdef _WIN32
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);
#endif

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        SSL_CTX_free(ctx);
#ifdef _WIN32
        WSACleanup();
#endif
        throw std::runtime_error("Failed to create socket");
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) {
#ifdef _WIN32
        closesocket(sock);
        WSACleanup();
#else
        close(sock);
#endif
        SSL_CTX_free(ctx);
        throw std::runtime_error("Invalid server IP address");
    }

    if (connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
#ifdef _WIN32
        closesocket(sock);
        WSACleanup();
#else
        close(sock);
#endif
        SSL_CTX_free(ctx);
        throw std::runtime_error("Connection failed");
    }

    SSL* ssl = SSL_new(ctx);
    SSL_set_fd(ssl, sock);
    if (SSL_connect(ssl) <= 0) {
        ERR_print_errors_fp(stderr);
#ifdef _WIN32
        closesocket(sock);
        WSACleanup();
#else
        close(sock);
#endif
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        throw std::runtime_error("Failed to create SSL connection");
    }

    // Serialize the JSON payload to a string
    Json::StreamWriterBuilder writer;
    std::string payloadJson = Json::writeString(writer, payload);

    // Send the payload
    if (SSL_write(ssl, payloadJson.c_str(), payloadJson.size()) <= 0) {
#ifdef _WIN32
        closesocket(sock);
        WSACleanup();
#else
        close(sock);
#endif
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        throw std::runtime_error("Failed to send data");
    }

    // Receive the response
    char buffer[4096];
    int bytesRead = SSL_read(ssl, buffer, sizeof(buffer) - 1);
    if (bytesRead < 0) {
#ifdef _WIN32
        closesocket(sock);
        WSACleanup();
#else
        close(sock);
#endif
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        throw std::runtime_error("Failed to receive data");
    }

    buffer[bytesRead] = '\0'; // Null-terminate the received data

    SSL_free(ssl);
#ifdef _WIN32
    closesocket(sock);
    WSACleanup();
#else
    close(sock);
#endif
    SSL_CTX_free(ctx);
    cleanup_openssl();

    return std::string(buffer);
}

int main(int argc, char* argv[]) {
    try {
        auto args = parseArguments(argc, argv);

        // Extract required parameters
        std::string serverIp = args["--server-ip"];
        int serverPort = std::stoi(args["--server-port"]);
        std::string email = args["--email"];
        std::string password = args["--password"];

        if (serverIp.empty() || serverPort == 0 || email.empty() || password.empty()) {
            std::cerr << "❌ ERROR: Missing required parameters.\n";
            return 1;
        }

        std::cout << "🔐 Logging in...\n";

        // Build the payload
        Json::Value payload;
        payload["command"] = "login";
        payload["arguments"]["email"] = email;
        payload["arguments"]["password"] = password;

        // Send request and get response
        std::string responseJson = sendRequest(serverIp, serverPort, payload);

        // Parse and print the server response
        Json::CharReaderBuilder reader;
        Json::Value response;
        std::istringstream responseStream(responseJson);
        std::string errs;

        if (!Json::parseFromStream(reader, responseStream, &response, &errs)) {
            throw std::runtime_error("Failed to parse server response: " + errs);
        }

        std::cout << "✅ Server Response:\n" << response.toStyledString();
    } catch (const std::exception& e) {
        std::cerr << "❌ ERROR: " << e.what() << '\n';
        return 1;
    }

    return 0;
}

```

--------------------------------------------------------------------------------
/src/logger.js:
--------------------------------------------------------------------------------

```javascript
// logger.js
import winston from 'winston';
import chalk from 'chalk';
import stripAnsi from 'strip-ansi';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// ESM-Äquivalent von __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Bestimmen Sie den Pfad zur Log-Datei relativ zu `logger.js`
const LOG_FILE_PATH = path.join(__dirname, '../logs/server.log'); // Passen Sie den Pfad nach Bedarf an

// Hilfsfunktionen für Symbole und Farben
function getLevelSymbol(level) {
    const symbols = {
        info: 'ℹ️',
        warn: '⚠️',
        error: '❌',
        debug: '🐞',
    };
    return symbols[level] || '';
}

function chalkForLevel(level) {
    const levels = {
        info: chalk.blue,
        warn: chalk.yellow,
        error: chalk.red,
        debug: chalk.green,
    };
    return levels[level] || chalk.white;
}

// Variable zur Steuerung der Dateiausgabe
let allowWrittenLogfile = false;

// Initialisieren der Transports mit nur der Konsolenausgabe
const transports = [
    new winston.transports.Console({
        format: winston.format.combine(
            winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
            winston.format.printf(({ timestamp, level, message }) => {
                const symbol = getLevelSymbol(level);
                const coloredMessage = `${chalkForLevel(level)(symbol)} ${message}`;
                return `${timestamp} | ${coloredMessage}`;
            })
        ),
    }),
];

// Erstellen des Winston-Loggers
const logger = winston.createLogger({
    level: 'info',
    transports: transports,
});

/**
 * Funktion zum Hinzufügen des File-Transports
 */
function addFileTransport() {
    const logDir = path.dirname(LOG_FILE_PATH);
    if (!fs.existsSync(logDir)) {
        fs.mkdirSync(logDir, { recursive: true });
    }

    const fileTransport = new winston.transports.File({
        filename: LOG_FILE_PATH,
        level: 'info', // Stellen Sie sicher, dass der Level ausreichend niedrig ist
        maxsize: 10485760, // 10 MB pro Datei
        maxFiles: 5, // Maximal 5 Dateien
        format: winston.format.combine(
            winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
            winston.format.printf(({ timestamp, level, message }) => {
                const symbol = getLevelSymbol(level);
                const plainMessage = stripAnsi(`${symbol} ${message}`); // ANSI-Codes entfernen
                return `${timestamp} | ${plainMessage}`;
            })
        ),
    });

    // Fehler-Handler hinzufügen
    fileTransport.on('error', (error) => {
        console.error(chalk.red('File-Transport Fehler:'), error);
    });

    // Prüfen, ob der Transport bereits hinzugefügt wurde, um Duplikate zu vermeiden
    if (!logger.transports.some(t => t instanceof winston.transports.File)) {
        logger.add(fileTransport);
    }
}

/**
 * Funktion zum Entfernen des File-Transports
 */
function removeFileTransport() {
    const fileTransport = logger.transports.find(
        (t) => t instanceof winston.transports.File
    );
    if (fileTransport) {
        logger.remove(fileTransport);
    }
}

/**
 * Funktion zum Setzen von allowWrittenLogfile
 * @param {boolean} value - true, um Dateilogs zu erlauben; false, um sie zu deaktivieren
 */
function setAllowWrittenLogfile(value) {
    allowWrittenLogfile = value;
    if (allowWrittenLogfile) {
        addFileTransport();
        logEvent('system', 'wrlog', 'File logs activated.', 'File logs are now activated.', 'info');
        
        // Überprüfen, ob der File-Transport hinzugefügt wurde
        const fileTransport = logger.transports.find(t => t instanceof winston.transports.File);
        if (fileTransport) {
            // console.log(chalk.green('File-Transport erfolgreich hinzugefügt.'));
        } else {
            console.log(chalk.red('Error: File transport could not be added.'));
        }
    } else {
        removeFileTransport();
        logEvent('system', 'wrlog', 'File logs deactivated.', 'File logs are now deactivated.', 'info');
    }
}

/**
 * Zentrale Logging-Funktion
 * @param {string} clientIP - IP-Adresse des Clients
 * @param {number|string} clientPort - Port des Clients
 * @param {string} functionName - Name der aufgerufenen Funktion
 * @param {string|object} status - Status der Rückmeldung
 * @param {string} level - Log-Level ('info', 'warn', 'error', 'debug')
 */
function logEvent(clientIP, clientPort, functionName, status, level = 'info') {
    // Kürzen und formatieren der Felder
    const ip = String(clientIP || 'N/A').padEnd(23).substring(0, 23); // Mindestens 8 Zeichen für die IP
    const port = String(clientPort || 'N/A').padEnd(5).substring(0, 5); // 5 Zeichen für den Port
    const func = String(functionName || 'N/A').padEnd(26).substring(0, 26); // 20 Zeichen für den Funktionsnamen
    const stat = String(status || '').padEnd(120).substring(0, 120); // 100 Zeichen für den Status

    // Formatierte Logzeile
    const logLine = `${ip}:${port} | ${func} | ${stat}`;
    // Log-Ausgabe basierend auf dem Level
    logger.log({ level, message: logLine });
}


export { logger, logEvent, setAllowWrittenLogfile, LOG_FILE_PATH };

```

--------------------------------------------------------------------------------
/clients/C++/5.1 mcp_edit_user/MCPEditUserClient.cpp:
--------------------------------------------------------------------------------

```cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <sstream>
#include <stdexcept>
#include <json/json.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib") // Verlinkung mit der Winsock-Bibliothek

// Funktion zum Parsen von Argumenten
std::map<std::string, std::string> parseArguments(int argc, char* argv[]) {
    std::map<std::string, std::string> args;
    for (int i = 1; i < argc; ++i) {
        std::string key = argv[i];
        if (i + 1 < argc && key.rfind("--", 0) == 0) {
            args[key] = argv[++i];
        }
    }
    return args;
}

// Funktion zum Parsen von Listen-Argumenten
std::vector<std::string> parseListArgument(int argc, char* argv[], const std::string& key) {
    std::vector<std::string> values;
    for (int i = 1; i < argc; ++i) {
        if (argv[i] == key && i + 1 < argc) {
            for (int j = i + 1; j < argc && std::string(argv[j]).rfind("--", 0) != 0; ++j) {
                values.push_back(argv[j]);
            }
        }
    }
    return values;
}

// Funktion zum Senden der Anfrage
std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) {
    Json::StreamWriterBuilder writer;
    std::string payloadJson = Json::writeString(writer, payload);

    // Winsock initialisieren
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        throw std::runtime_error("Failed to initialize Winsock.");
    }

    // Socket erstellen
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        WSACleanup();
        throw std::runtime_error("Failed to create socket.");
    }

    // Server-Adresse konfigurieren
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(serverPort);
    if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) {
        closesocket(sock);
        WSACleanup();
        throw std::runtime_error("Invalid server IP address.");
    }

    // Verbindung herstellen
    if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
        closesocket(sock);
        WSACleanup();
        throw std::runtime_error("Connection failed.");
    }

    // Daten senden
    if (send(sock, payloadJson.c_str(), payloadJson.size(), 0) < 0) {
        closesocket(sock);
        WSACleanup();
        throw std::runtime_error("Failed to send data.");
    }

    // Antwort empfangen
    char buffer[4096];
    int bytesRead;
    std::ostringstream response;

    do {
        bytesRead = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (bytesRead > 0) {
            buffer[bytesRead] = '\0'; // Null-terminieren
            response << buffer;
        }
    } while (bytesRead == sizeof(buffer) - 1);

    // Socket schließen
    closesocket(sock);
    WSACleanup();

    return response.str();
}

int main(int argc, char* argv[]) {
    try {
        auto args = parseArguments(argc, argv);

        // Pflichtargumente überprüfen
        if (args["--server-ip"].empty() || args["--server-port"].empty() || args["--token"].empty() || args["--email"].empty() || args["--name"].empty()) {
            std::cerr << "Usage: --server-ip <IP> --server-port <PORT> --token <TOKEN> --email <EMAIL> --name <NAME> [optional parameters]\n";
            return 1;
        }

        // Argumente auslesen
        std::string serverIp = args["--server-ip"];
        int serverPort = std::stoi(args["--server-port"]);
        std::string token = args["--token"];
        std::string email = args["--email"];
        std::string name = args["--name"];
        std::string language = args.count("--language") ? args["--language"] : "en";
        std::string timezone = args.count("--timezone") ? args["--timezone"] : "UTC";
        std::string password = args["--password"];
        bool publicUpload = args.count("--publicUpload") > 0;
        auto groups = parseListArgument(argc, argv, "--groups");
        auto roles = parseListArgument(argc, argv, "--roles");
        bool activateFtp = args.count("--activateFtp") > 0;
        std::string ftpPassword = args["--ftpPassword"];

        // JSON-Payload erstellen
        Json::Value payload;
        payload["command"] = "edit_user";
        payload["token"] = token;
        payload["arguments"]["email"] = email;
        payload["arguments"]["name"] = name;
        payload["arguments"]["language"] = language;
        payload["arguments"]["timezone"] = timezone;
        if (!password.empty()) payload["arguments"]["password"] = password;
        payload["arguments"]["publicUpload"] = publicUpload;
        for (const auto& group : groups) {
            payload["arguments"]["groups"].append(group);
        }
        for (const auto& role : roles) {
            payload["arguments"]["roles"].append(role);
        }
        payload["arguments"]["activateFtp"] = activateFtp;
        if (!ftpPassword.empty()) payload["arguments"]["ftpPassword"] = ftpPassword;

        std::cout << "📤 Sending edit user request...\n";

        // Anfrage senden und Antwort erhalten
        std::string response = sendRequest(serverIp, serverPort, payload);

        std::cout << "✔️ Response from server:\n" << response << "\n";
    } catch (const std::exception& e) {
        std::cerr << "❌ ERROR: " << e.what() << "\n";
        return 1;
    }

    return 0;
}

```

--------------------------------------------------------------------------------
/clients/JavaScript/3.3 mcp_edit_source/MCPEditSourceClient.js:
--------------------------------------------------------------------------------

```javascript
const net = require('net');
const readline = require('readline');
const { argv, exit } = require('process');

// Funktion zum Parsen der Kommandozeilenargumente
function parseArguments(args) {
    const parsedArgs = {};
    for (let i = 2; i < args.length; i++) {
        switch (args[i]) {
            case '--server-ip':
                parsedArgs.serverIp = args[++i];
                break;
            case '--server-port':
                parsedArgs.serverPort = parseInt(args[++i], 10);
                break;
            case '--token':
                parsedArgs.token = args[++i];
                break;
            case '--source-id':
                parsedArgs.sourceId = args[++i];
                break;
            case '--title':
                parsedArgs.title = args[++i];
                break;
            case '--content':
                parsedArgs.content = args[++i];
                break;
            case '--groups':
                // Sammle alle Gruppenargumente bis zum nächsten Flag oder Ende
                parsedArgs.groups = [];
                while (i + 1 < args.length && !args[i + 1].startsWith('--')) {
                    parsedArgs.groups.push(args[++i]);
                }
                break;
            default:
                console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
        }
    }
    return parsedArgs;
}

// Funktion zum interaktiven Abfragen eines Parameters (optional)
function askQuestion(query) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: true
    });

    return new Promise((resolve) => {
        rl.question(query, (answer) => {
            rl.close();
            resolve(answer);
        });
    });
}

// Funktion zum Senden einer Edit-Source-Anfrage über eine TCP-Verbindung
function sendEditSourceRequest(serverIp, serverPort, payload) {
    return new Promise((resolve, reject) => {
        const client = new net.Socket();
        let responseData = '';

        client.connect(serverPort, serverIp, () => {
            console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
            const payloadString = JSON.stringify(payload);
            console.log(`📤 Sende Payload: ${payloadString}`);
            client.write(payloadString);
        });

        client.on('data', (data) => {
            console.log(`📥 Empfangene Daten: ${data}`);
            responseData += data.toString();
            try {
                const parsedData = JSON.parse(responseData);
                console.log('✅ JSON-Antwort erfolgreich geparst.');
                resolve(parsedData);
                client.destroy(); // Verbindung schließen
            } catch (err) {
                console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.');
                // Antwort noch nicht vollständig, weiter empfangen
            }
        });

        client.on('close', () => {
            console.log('🔒 Verbindung zum Server geschlossen.');
        });

        client.on('error', (err) => {
            console.error('❌ Verbindungsfehler:', err.message);
            reject(err);
        });
    });
}

// Hauptfunktion
async function main() {
    const args = argv;
    const parsedArgs = parseArguments(args);
    let { serverIp, serverPort, token, sourceId, title, content, groups } = parsedArgs;

    // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen
    if (!serverIp) {
        serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: ');
    }
    if (!serverPort) {
        const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: ');
        serverPort = parseInt(portInput, 10);
    }
    if (!token) {
        token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: ');
    }
    if (!sourceId) {
        sourceId = await askQuestion('📁 Bitte gib die Source-ID ein: ');
    }

    // Überprüfen, ob mindestens eines der optionalen Parameter vorhanden ist
    if (title === undefined && content === undefined && (groups === undefined || groups.length === 0)) {
        console.warn('⚠️ Keine Änderungsparameter angegeben. Es werden mindestens eines der folgenden benötigt: --title, --content, --groups.');
        exit(1);
    }

    // Optional: Abfrage fehlender optionaler Parameter, wenn entsprechende Flags gesetzt sind
    // Hier gehen wir davon aus, dass --title, --content und --groups bereits korrekt geparst wurden
    // und entweder definiert sind oder nicht angegeben wurden.

    // Entferne unerwünschte Schlüssel mit undefined oder null Werten
    const filteredArguments = {};
    if (sourceId) filteredArguments.sourceId = sourceId;
    if (title) filteredArguments.title = title;
    if (content) filteredArguments.content = content;
    if (groups && groups.length > 0) filteredArguments.groups = groups;

    const payload = {
        command: "edit_source",
        token: token,
        arguments: filteredArguments
    };

    try {
        console.log('🛠️ Sende Edit-Source-Anfrage...');
        const response = await sendEditSourceRequest(serverIp, serverPort, payload);
        console.log('✅ Server Response:');
        console.log(JSON.stringify(response, null, 2));
    } catch (err) {
        console.error('❌ ERROR:', err.message);
    }
}

main();

```

--------------------------------------------------------------------------------
/clients/JavaScript/4.1 mcp_store_group/MCPStoreGroupClient.js:
--------------------------------------------------------------------------------

```javascript
const net = require('net');
const readline = require('readline');
const { argv, exit } = require('process');

/**
 * Funktion zum Parsen der Kommandozeilenargumente
 * @param {string[]} args - Array von Kommandozeilenargumenten
 * @returns {Object} - Objekt mit geparsten Argumenten
 */
function parseArguments(args) {
    const parsedArgs = {};
    for (let i = 2; i < args.length; i++) {
        switch (args[i]) {
            case '--server-ip':
                parsedArgs.serverIp = args[++i];
                break;
            case '--server-port':
                parsedArgs.serverPort = parseInt(args[++i], 10);
                break;
            case '--group-name':
                parsedArgs.groupName = args[++i];
                break;
            case '--token':
                parsedArgs.token = args[++i];
                break;
            case '--description':
                parsedArgs.description = args[++i];
                break;
            default:
                console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
        }
    }
    return parsedArgs;
}

/**
 * Funktion zum interaktiven Abfragen eines Parameters (optional)
 * @param {string} query - Frage an den Benutzer
 * @returns {Promise<string>} - Antwort des Benutzers
 */
function askQuestion(query) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: true
    });

    return new Promise((resolve) => {
        rl.question(query, (answer) => {
            rl.close();
            resolve(answer);
        });
    });
}

/**
 * Sendet eine Anfrage an den MCP-Server, um eine neue Gruppe zu speichern.
 *
 * @param {string} serverIp - IP-Adresse des MCP-Servers
 * @param {number} serverPort - Portnummer des MCP-Servers
 * @param {string} groupName - Name der zu speichernden Gruppe
 * @param {string} token - Authentifizierungstoken
 * @param {string} description - Beschreibung der Gruppe (optional)
 * @returns {Promise<Object>} - Antwort vom Server
 */
function sendStoreGroupRequest(serverIp, serverPort, groupName, token, description) {
    return new Promise((resolve, reject) => {
        const client = new net.Socket();
        const payload = {
            command: "store_group",
            token: token,
            arguments: {
                groupName: groupName,
                description: description
            }
        };
        const payloadString = JSON.stringify(payload);

        // Timeout setzen (optional)
        const TIMEOUT_DURATION = 10000; // 10 Sekunden
        const timeout = setTimeout(() => {
            client.destroy(); // Verbindung zerstören
            reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.'));
        }, TIMEOUT_DURATION);

        client.connect(serverPort, serverIp, () => {
            console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
            console.log(`📤 Sende Payload: ${payloadString}`);
            client.write(payloadString);
        });

        let responseData = '';

        client.on('data', (data) => {
            console.log(`📥 Empfangene Daten: ${data}`);
            responseData += data.toString();
            try {
                const parsedData = JSON.parse(responseData);
                console.log('✅ JSON-Antwort erfolgreich geparst.');
                clearTimeout(timeout);
                resolve(parsedData);
                client.destroy(); // Verbindung schließen
            } catch (err) {
                console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.');
                // Weiter empfangen
            }
        });

        client.on('close', () => {
            console.log('🔒 Verbindung zum Server geschlossen.');
            clearTimeout(timeout);
        });

        client.on('error', (err) => {
            console.error('❌ Verbindungsfehler:', err.message);
            clearTimeout(timeout);
            reject(err);
        });
    });
}

// Hauptfunktion
async function main() {
    const args = argv;
    const parsedArgs = parseArguments(args);
    let { serverIp, serverPort, groupName, token, description } = parsedArgs;

    // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen
    if (!serverIp) {
        serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: ');
    }
    if (!serverPort) {
        const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: ');
        serverPort = parseInt(portInput, 10);
    }
    if (!groupName) {
        groupName = await askQuestion('📛 Bitte gib den Gruppennamen ein: ');
    }
    if (!token) {
        token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: ');
    }
    // Beschreibung ist optional, kein Abfrage notwendig

    const payload = {
        command: "store_group",
        token: token,
        arguments: {
            groupName: groupName,
            description: description || ""
        }
    };

    try {
        console.log('🗃️ Sende Store-Group-Anfrage...');
        const response = await sendStoreGroupRequest(serverIp, serverPort, groupName, token, description);
        console.log('✔️ Antwort vom Server:', JSON.stringify(response, null, 2));
    } catch (err) {
        console.error('❌ Fehler:', err.message);
    }
}

main();

```

--------------------------------------------------------------------------------
/clients/JavaScript/5.1 mcp_edit_user/MCPEditUserClient.js:
--------------------------------------------------------------------------------

```javascript
const net = require('net');
const readline = require('readline');
const { argv } = require('process');

/**
 * Funktion zum Parsen der Kommandozeilenargumente
 * @param {string[]} args - Array von Kommandozeilenargumenten
 * @returns {Object} - Objekt mit geparsten Argumenten
 */
function parseArguments(args) {
    const parsedArgs = {};
    for (let i = 2; i < args.length; i++) {
        switch (args[i]) {
            case '--server-ip':
                parsedArgs.serverIp = args[++i];
                break;
            case '--server-port':
                parsedArgs.serverPort = parseInt(args[++i], 10);
                break;
            case '--token':
                parsedArgs.token = args[++i];
                break;
            case '--name':
                parsedArgs.name = args[++i];
                break;
            case '--email':
                parsedArgs.email = args[++i];
                break;
            case '--password':
                parsedArgs.password = args[++i];
                break;
            case '--language':
                parsedArgs.language = args[++i];
                break;
            case '--timezone':
                parsedArgs.timezone = args[++i];
                break;
            case '--roles':
                parsedArgs.roles = [];
                while (i + 1 < args.length && !args[i + 1].startsWith('--')) {
                    parsedArgs.roles.push(args[++i]);
                }
                break;
            case '--groups':
                parsedArgs.groups = [];
                while (i + 1 < args.length && !args[i + 1].startsWith('--')) {
                    parsedArgs.groups.push(args[++i]);
                }
                break;
            case '--usePublic':
                parsedArgs.usePublic = true;
                break;
            case '--activateFtp':
                parsedArgs.activateFtp = true;
                break;
            case '--ftpPassword':
                parsedArgs.ftpPassword = args[++i];
                break;
            default:
                console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
        }
    }
    return parsedArgs;
}

/**
 * Sendet eine Anfrage an den MCP-Server, um einen Benutzer zu bearbeiten.
 *
 * @param {string} serverIp - IP-Adresse des MCP-Servers
 * @param {number} serverPort - Portnummer des MCP-Servers
 * @param {string} token - Authentifizierungstoken
 * @param {Object} args - Argumente für den zu bearbeitenden Benutzer
 * @returns {Promise<string>} - Antwort vom Server
 */
function sendEditUserRequest(serverIp, serverPort, token, args) {
    return new Promise((resolve, reject) => {
        const client = new net.Socket();
        const payload = {
            command: "edit_user",
            token: token,
            arguments: {
                name: args.name,
                email: args.email,
                password: args.password,
                language: args.language,
                timezone: args.timezone,
                roles: args.roles || [],
                groups: args.groups || [],
                usePublic: args.usePublic || false,
                activateFtp: args.activateFtp || false,
                ftpPassword: args.ftpPassword
            }
        };

        // Entferne Null- oder undefined-Werte
        payload.arguments = Object.fromEntries(Object.entries(payload.arguments).filter(([_, v]) => v != null));

        const payloadString = JSON.stringify(payload);

        // Timeout setzen
        const TIMEOUT_DURATION = 10000; // 10 Sekunden
        const timeout = setTimeout(() => {
            client.destroy();
            reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.'));
        }, TIMEOUT_DURATION);

        client.connect(serverPort, serverIp, () => {
            console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
            console.log(`📤 Sende Payload: ${payloadString}`);
            client.write(payloadString);
        });

        let responseData = '';

        client.on('data', (data) => {
            responseData += data.toString();
            try {
                const parsedData = JSON.parse(responseData);
                clearTimeout(timeout);
                resolve(parsedData);
                client.destroy();
            } catch (e) {
                // Weiter empfangen, falls JSON unvollständig ist
            }
        });

        client.on('close', () => {
            console.log('🔒 Verbindung zum Server geschlossen.');
        });

        client.on('error', (err) => {
            clearTimeout(timeout);
            reject(err);
        });
    });
}

// Hauptfunktion
async function main() {
    const args = parseArguments(argv);

    if (!args.serverIp || !args.serverPort || !args.token) {
        console.error('❌ Fehler: --server-ip, --server-port und --token sind erforderlich.');
        console.log('📖 Beispiel: node MCPEditUserClient.js --server-ip 192.168.0.1 --server-port 5000 --token YOUR_AUTH_TOKEN');
        process.exit(1);
    }

    try {
        console.log('🧑‍💻 Sende Edit-User-Anfrage...');
        const response = await sendEditUserRequest(
            args.serverIp,
            args.serverPort,
            args.token,
            args
        );
        console.log('✔️ Antwort vom Server:', JSON.stringify(response, null, 2));
    } catch (err) {
        console.error('❌ Fehler beim Bearbeiten des Benutzers:', err.message);
    }
}

main();

```

--------------------------------------------------------------------------------
/clients/Java/2.0 mcp_chat/MCPChatClient.java:
--------------------------------------------------------------------------------

```java
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MCPChatClient {

    public static void main(String[] args) {
        // Minimalprüfung, ob genug Argumente für --server-ip, --server-port, --token, --question vorliegen.
        // (Die eigentliche Prüfung machen wir etwas weiter unten ausführlicher.)
        if (args.length < 5) {
            printUsage();
            return;
        }

        // Argumente auslesen
        String serverIp = getArgument(args, "--server-ip");
        String serverPortStr = getArgument(args, "--server-port");
        String token = getArgument(args, "--token");
        String question = getArgument(args, "--question");
        boolean usePublic = Arrays.asList(args).contains("--use-public");
        String language = getArgument(args, "--language");
        if (language == null) {
            language = "de"; // Defaultwert wie im Original
        }

        // Groups (kommagetrennt)
        List<String> groups = new ArrayList<>();
        String groupsArgument = getArgument(args, "--groups");
        if (groupsArgument != null) {
            // Zerlege den String an Kommas
            String[] groupArray = groupsArgument.split(",");
            groups.addAll(Arrays.asList(groupArray));
        }

        // Vollständige Prüfung
        if (serverIp == null || serverPortStr == null || token == null || question == null) {
            printUsage();
            return;
        }

        int serverPort = Integer.parseInt(serverPortStr);

        // Anfrage an den Server stellen
        String response = sendMCPRequest(serverIp, serverPort, token, question, usePublic, groups, language);
        System.out.println("Response from server:");
        System.out.println(response);
    }

    /**
     * Liest den Wert eines Arguments aus (z.B. --server-ip 127.0.0.1).
     * Gibt null zurück, wenn der Schlüssel nicht gefunden wurde.
     */
    private static String getArgument(String[] args, String key) {
        for (int i = 0; i < args.length - 1; i++) {
            if (args[i].equals(key)) {
                // Gib das nächste Element zurück, sofern vorhanden
                return args[i + 1];
            }
        }
        return null;
    }

    /**
     * Stellt eine Socket-Verbindung her, sendet das JSON-Payload und empfängt die Antwort.
     */
    private static String sendMCPRequest(String serverIp,
                                         int serverPort,
                                         String token,
                                         String question,
                                         boolean usePublic,
                                         List<String> groups,
                                         String language) {

        // Payload aufbauen
        JSONObject payload = new JSONObject();
        payload.put("command", "chat");
        payload.put("token", token);

        // arguments
        JSONObject arguments = new JSONObject();
        arguments.put("question", question);
        arguments.put("usePublic", usePublic);
        arguments.put("language", language);

        // Falls du lieber ein reines Array statt List speichern möchtest,
        // kannst du direkt new JSONArray(groups) verwenden.
        // Hier konvertieren wir die Java-Liste in ein JSONArray:
        JSONArray groupsArray = new JSONArray(groups);
        arguments.put("groups", groupsArray);

        payload.put("arguments", arguments);

        // Konvertiere das JSON-Objekt in einen String
        String payloadJson = payload.toString();

        try (Socket client = new Socket(serverIp, serverPort)) {
            // Sende das JSON-Payload
            OutputStream outputStream = client.getOutputStream();
            byte[] data = payloadJson.getBytes(StandardCharsets.UTF_8);
            outputStream.write(data);
            outputStream.flush();

            // Antwort empfangen
            InputStream inputStream = client.getInputStream();
            byte[] buffer = new byte[4096];
            StringBuilder responseBuilder = new StringBuilder();

            int bytesRead;
            do {
                bytesRead = inputStream.read(buffer);
                if (bytesRead > 0) {
                    responseBuilder.append(new String(buffer, 0, bytesRead, StandardCharsets.UTF_8));
                }
            } while (bytesRead == buffer.length);

            return responseBuilder.toString();

        } catch (IOException e) {
            // Fehler in ein JSON-Objekt packen, wie im Original
            JSONObject errorResponse = new JSONObject();
            errorResponse.put("status", "error");
            errorResponse.put("message", e.getMessage());
            return errorResponse.toString();
        }
    }

    private static void printUsage() {
        System.out.println("Usage: ");
        System.out.println("  --server-ip <IP> --server-port <PORT> --token <TOKEN> --question <QUESTION>");
        System.out.println("  [--use-public] [--groups <GROUPS>] [--language <LANGUAGE>]");
        System.out.println();
        System.out.println("Example:");
        System.out.println("  java -cp .;json-20241224.jar MCPChatClient --server-ip 127.0.0.1 --server-port 1234 \\");
        System.out.println("       --token 12345 --question \"Hallo Welt?\" --use-public --groups \"devops,hr\"");
    }
}

```

--------------------------------------------------------------------------------
/clients/Gradio/transport/stdio/stdio_client.py:
--------------------------------------------------------------------------------

```python
# transport/stdio/stdio_client.py
import json
import logging
import sys
import traceback
from contextlib import asynccontextmanager

import anyio
from anyio.streams.text import TextReceiveStream

from ...mcp_client import get_default_environment
from ...messages.message_types.json_rpc_message import JSONRPCMessage
from ...transport.stdio.stdio_server_parameters import StdioServerParameters


@asynccontextmanager
async def stdio_client(server: StdioServerParameters):
    # ensure we have a server command
    if not server.command:
        raise ValueError("Server command must not be empty.")

    # ensure we have server arguments as a list or tuple
    if not isinstance(server.args, (list, tuple)):
        raise ValueError("Server arguments must be a list or tuple.")

    # create the the read and write streams
    read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
    write_stream, write_stream_reader = anyio.create_memory_object_stream(0)

    # start the subprocess
    process = await anyio.open_process(
        [server.command, *server.args],
        env={**get_default_environment(), **(server.env or {})},
        stderr=sys.stderr,
    )

    # started server
    logging.debug(
        f"Subprocess started with PID {process.pid}, command: {server.command}"
    )

    # create a task to read from the subprocess' stdout
    async def process_json_line(line: str, writer):
        try:
            logging.debug(f"Processing line: {line.strip()}")
            data = json.loads(line)

            # parse the json
            logging.debug(f"Parsed JSON data: {data}")

            # validate the jsonrpc message
            message = JSONRPCMessage.model_validate(data)
            logging.debug(f"Validated JSONRPCMessage: {message}")

            # send the message
            await writer.send(message)
        except json.JSONDecodeError as exc:
            # not valid json
            logging.error(f"JSON decode error: {exc}. Line: {line.strip()}")
        except Exception as exc:
            # other exception
            logging.error(f"Error processing message: {exc}. Line: {line.strip()}")
            logging.debug(f"Traceback:\n{traceback.format_exc()}")

    async def stdout_reader():
        """Read JSON-RPC messages from the server's stdout."""
        assert process.stdout, "Opened process is missing stdout"
        buffer = ""
        logging.debug("Starting stdout_reader")
        try:
            async with read_stream_writer:
                async for chunk in TextReceiveStream(process.stdout):
                    lines = (buffer + chunk).split("\n")
                    buffer = lines.pop()
                    for line in lines:
                        if line.strip():
                            await process_json_line(line, read_stream_writer)
                if buffer.strip():
                    await process_json_line(buffer, read_stream_writer)
        except anyio.ClosedResourceError:
            logging.debug("Read stream closed.")
        except Exception as exc:
            logging.error(f"Unexpected error in stdout_reader: {exc}")
            logging.debug(f"Traceback:\n{traceback.format_exc()}")
            raise
        finally:
            logging.debug("Exiting stdout_reader")

    async def stdin_writer():
        """Send JSON-RPC messages from the write stream to the server's stdin."""
        assert process.stdin, "Opened process is missing stdin"
        logging.debug("Starting stdin_writer")
        try:
            async with write_stream_reader:
                async for message in write_stream_reader:
                    json_str = message.model_dump_json(exclude_none=True)
                    logging.debug(f"Sending: {json_str}")
                    await process.stdin.send((json_str + "\n").encode())
        except anyio.ClosedResourceError:
            logging.debug("Write stream closed.")
        except Exception as exc:
            logging.error(f"Unexpected error in stdin_writer: {exc}")
            logging.debug(f"Traceback:\n{traceback.format_exc()}")
            raise
        finally:
            logging.debug("Exiting stdin_writer")

    async def terminate_process():
        """Gracefully terminate the subprocess."""
        try:
            if process.returncode is None:  # Process is still running
                logging.debug("Terminating subprocess...")
                process.terminate()
                with anyio.fail_after(5):
                    await process.wait()
            else:
                logging.info("Process already terminated.")
        except TimeoutError:
            logging.warning(
                "Process did not terminate gracefully. Forcefully killing it."
            )
            try:
                process.kill()
            except Exception as kill_exc:
                logging.error(f"Error killing process: {kill_exc}")
        except Exception as exc:
            logging.error(f"Error during process termination: {exc}")

    try:
        async with anyio.create_task_group() as tg, process:
            tg.start_soon(stdout_reader)
            tg.start_soon(stdin_writer)
            yield read_stream, write_stream

        # exit the task group
        exit_code = await process.wait()
        logging.info(f"Process exited with code {exit_code}")
    except Exception as exc:
        # other exception
        logging.error(f"Unhandled error in TaskGroup: {exc}")
        logging.debug(f"Traceback:\n{traceback.format_exc()}")
        if hasattr(exc, "__cause__") and exc.__cause__:
            logging.debug(f"TaskGroup exception cause: {exc.__cause__}")
        raise
    finally:
        await terminate_process()

```

--------------------------------------------------------------------------------
/agents/MCP-Client/Python/transport/stdio/stdio_client.py:
--------------------------------------------------------------------------------

```python
# transport/stdio/stdio_client.py
import json
import logging
import sys
import traceback
from contextlib import asynccontextmanager

import anyio
from anyio.streams.text import TextReceiveStream

from ...environment import get_default_environment
from ...messages.message_types.json_rpc_message import JSONRPCMessage
from ...transport.stdio.stdio_server_parameters import StdioServerParameters


@asynccontextmanager
async def stdio_client(server: StdioServerParameters):
    # ensure we have a server command
    if not server.command:
        raise ValueError("Server command must not be empty.")

    # ensure we have server arguments as a list or tuple
    if not isinstance(server.args, (list, tuple)):
        raise ValueError("Server arguments must be a list or tuple.")

    # create the the read and write streams
    read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
    write_stream, write_stream_reader = anyio.create_memory_object_stream(0)

    # start the subprocess
    process = await anyio.open_process(
        [server.command, *server.args],
        env={**get_default_environment(), **(server.env or {})},
        stderr=sys.stderr,
    )

    # started server
    logging.debug(
        f"Subprocess started with PID {process.pid}, command: {server.command}"
    )

    # create a task to read from the subprocess' stdout
    async def process_json_line(line: str, writer):
        try:
            logging.debug(f"Processing line: {line.strip()}")
            data = json.loads(line)

            # parse the json
            logging.debug(f"Parsed JSON data: {data}")

            # validate the jsonrpc message
            message = JSONRPCMessage.model_validate(data)
            logging.debug(f"Validated JSONRPCMessage: {message}")

            # send the message
            await writer.send(message)
        except json.JSONDecodeError as exc:
            # not valid json
            logging.error(f"JSON decode error: {exc}. Line: {line.strip()}")
        except Exception as exc:
            # other exception
            logging.error(f"Error processing message: {exc}. Line: {line.strip()}")
            logging.debug(f"Traceback:\n{traceback.format_exc()}")

    async def stdout_reader():
        """Read JSON-RPC messages from the server's stdout."""
        assert process.stdout, "Opened process is missing stdout"
        buffer = ""
        logging.debug("Starting stdout_reader")
        try:
            async with read_stream_writer:
                async for chunk in TextReceiveStream(process.stdout):
                    lines = (buffer + chunk).split("\n")
                    buffer = lines.pop()
                    for line in lines:
                        if line.strip():
                            await process_json_line(line, read_stream_writer)
                if buffer.strip():
                    await process_json_line(buffer, read_stream_writer)
        except anyio.ClosedResourceError:
            logging.debug("Read stream closed.")
        except Exception as exc:
            logging.error(f"Unexpected error in stdout_reader: {exc}")
            logging.debug(f"Traceback:\n{traceback.format_exc()}")
            raise
        finally:
            logging.debug("Exiting stdout_reader")

    async def stdin_writer():
        """Send JSON-RPC messages from the write stream to the server's stdin."""
        assert process.stdin, "Opened process is missing stdin"
        logging.debug("Starting stdin_writer")
        try:
            async with write_stream_reader:
                async for message in write_stream_reader:
                    json_str = message.model_dump_json(exclude_none=True)
                    logging.debug(f"Sending: {json_str}")
                    await process.stdin.send((json_str + "\n").encode())
        except anyio.ClosedResourceError:
            logging.debug("Write stream closed.")
        except Exception as exc:
            logging.error(f"Unexpected error in stdin_writer: {exc}")
            logging.debug(f"Traceback:\n{traceback.format_exc()}")
            raise
        finally:
            logging.debug("Exiting stdin_writer")

    async def terminate_process():
        """Gracefully terminate the subprocess."""
        try:
            if process.returncode is None:  # Process is still running
                logging.debug("Terminating subprocess...")
                process.terminate()
                with anyio.fail_after(5):
                    await process.wait()
            else:
                logging.info("Process already terminated.")
        except TimeoutError:
            logging.warning(
                "Process did not terminate gracefully. Forcefully killing it."
            )
            try:
                process.kill()
            except Exception as kill_exc:
                logging.error(f"Error killing process: {kill_exc}")
        except Exception as exc:
            logging.error(f"Error during process termination: {exc}")

    try:
        async with anyio.create_task_group() as tg, process:
            tg.start_soon(stdout_reader)
            tg.start_soon(stdin_writer)
            yield read_stream, write_stream

        # exit the task group
        exit_code = await process.wait()
        logging.info(f"Process exited with code {exit_code}")
    except Exception as exc:
        # other exception
        logging.error(f"Unhandled error in TaskGroup: {exc}")
        logging.debug(f"Traceback:\n{traceback.format_exc()}")
        if hasattr(exc, "__cause__") and exc.__cause__:
            logging.debug(f"TaskGroup exception cause: {exc.__cause__}")
        raise
    finally:
        await terminate_process()

```

--------------------------------------------------------------------------------
/clients/JavaScript/4.2 mcp_delete_group/MCPDeleteGroupClient.js:
--------------------------------------------------------------------------------

```javascript
const net = require('net');
const readline = require('readline');
const { argv, exit } = require('process');

/**
 * Funktion zum Parsen der Kommandozeilenargumente
 * @param {string[]} args - Array von Kommandozeilenargumenten
 * @returns {Object} - Objekt mit geparsten Argumenten
 */
function parseArguments(args) {
    const parsedArgs = {};
    for (let i = 2; i < args.length; i++) {
        switch (args[i]) {
            case '--server-ip':
                if (i + 1 < args.length) {
                    parsedArgs.serverIp = args[++i];
                } else {
                    console.warn('⚠️ Kein Wert für --server-ip angegeben.');
                }
                break;
            case '--server-port':
                if (i + 1 < args.length) {
                    parsedArgs.serverPort = parseInt(args[++i], 10);
                } else {
                    console.warn('⚠️ Kein Wert für --server-port angegeben.');
                }
                break;
            case '--token':
                if (i + 1 < args.length) {
                    parsedArgs.token = args[++i];
                } else {
                    console.warn('⚠️ Kein Wert für --token angegeben.');
                }
                break;
            case '--group-name':
                if (i + 1 < args.length) {
                    parsedArgs.groupName = args[++i];
                } else {
                    console.warn('⚠️ Kein Wert für --group-name angegeben.');
                }
                break;
            default:
                console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
        }
    }
    return parsedArgs;
}

/**
 * Funktion zum interaktiven Abfragen eines Parameters (optional)
 * @param {string} query - Frage an den Benutzer
 * @returns {Promise<string>} - Antwort des Benutzers
 */
function askQuestion(query) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: true
    });

    return new Promise((resolve) => {
        rl.question(query, (answer) => {
            rl.close();
            resolve(answer);
        });
    });
}

/**
 * Sendet eine Anfrage an den MCP-Server, um eine bestehende Gruppe zu löschen.
 *
 * @param {string} serverIp - IP-Adresse des MCP-Servers
 * @param {number} serverPort - Portnummer des MCP-Servers
 * @param {string} token - Authentifizierungstoken
 * @param {string} groupName - Name der zu löschenden Gruppe
 * @returns {Promise<Object>} - Antwort vom Server
 */
function sendDeleteGroupRequest(serverIp, serverPort, token, groupName) {
    return new Promise((resolve, reject) => {
        const client = new net.Socket();
        const payload = {
            command: "delete_group",
            token: token,
            arguments: {
                groupName: groupName
            }
        };
        const payloadString = JSON.stringify(payload);

        // Timeout setzen (optional)
        const TIMEOUT_DURATION = 10000; // 10 Sekunden
        const timeout = setTimeout(() => {
            client.destroy(); // Verbindung zerstören
            reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.'));
        }, TIMEOUT_DURATION);

        client.connect(serverPort, serverIp, () => {
            console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
            console.log(`📤 Sende Payload: ${payloadString}`);
            client.write(payloadString);
        });

        let responseData = '';

        client.on('data', (data) => {
            console.log(`📥 Empfangene Daten: ${data}`);
            responseData += data.toString();
            try {
                const parsedData = JSON.parse(responseData);
                console.log('✅ JSON-Antwort erfolgreich geparst.');
                clearTimeout(timeout);
                resolve(parsedData);
                client.destroy(); // Verbindung schließen
            } catch (err) {
                console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.');
                // Weiter empfangen
            }
        });

        client.on('close', () => {
            console.log('🔒 Verbindung zum Server geschlossen.');
            clearTimeout(timeout);
        });

        client.on('error', (err) => {
            console.error('❌ Verbindungsfehler:', err.message);
            clearTimeout(timeout);
            reject(err);
        });
    });
}

// Hauptfunktion
async function main() {
    const args = argv;
    const parsedArgs = parseArguments(args);
    let { serverIp, serverPort, token, groupName } = parsedArgs;

    // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen
    if (!serverIp) {
        serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: ');
    }
    if (!serverPort) {
        const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: ');
        serverPort = parseInt(portInput, 10);
    }
    if (!token) {
        token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: ');
    }
    if (!groupName) {
        groupName = await askQuestion('👥 Bitte gib den Namen der Gruppe ein: ');
    }

    const payload = {
        command: "delete_group",
        token: token,
        arguments: {
            groupName: groupName
        }
    };

    try {
        console.log('🗑️ Sende Delete-Group-Anfrage...');
        const response = await sendDeleteGroupRequest(serverIp, serverPort, token, groupName);
        console.log('✔️ Antwort vom Server:', JSON.stringify(response, null, 2));
    } catch (err) {
        console.error('❌ Fehler:', err.message);
    }
}

main();

```

--------------------------------------------------------------------------------
/agents/OpenAI_Compatible_API_Agent/Python/openai_compatible_api.py:
--------------------------------------------------------------------------------

```python
import json
from pathlib import Path

from starlette.responses import StreamingResponse

from fastapi import FastAPI, Request, HTTPException
from threading import local

from agents.OpenAI_Compatible_API_Agent.Python.open_ai_helper import ChatInstance, \
    ChatCompletionRequest, CompletionRequest, _resp_sync, _resp_async_generator, models, Message, _resp_async_generator_completions, _resp_sync_completions
from .privategpt_api import PrivateGPTAPI

from ...AgentInterface.Python.config import Config, ConfigError
import uvicorn

app = FastAPI(title="OpenAI-compatible API for PrivateGPT")
request_context = local()
instances = []

# Konfiguration laden
try:
    config_file = Path.absolute(Path(__file__).parent.parent / "pgpt_openai_api_proxy.json")
    config = Config(config_file=config_file, required_fields=["base_url"])
    default_groups = config.get("groups", [])
except ConfigError as e:
    print(f"Configuration Error: {e}")
    exit(1)



@app.middleware("http")
async def store_request_headers(request: Request, call_next):
    request_context.headers = dict(request.headers)
    response = await call_next(request)
    return response


@app.post("/chat/completions")
async def chat_completions(request: ChatCompletionRequest):
    headers = getattr(request_context, "headers", {})
    client_api_key = str(headers['authorization']).split(" ")[1]
    groups = default_groups
    force_new_session = False

    if request.groups:
        groups = request.groups
    if request.newSession:
        force_new_session = True

    print("Groups: " + str(groups))

    if  request.messages:
        #Check if this api-key already has a running instance
        indices = [i for i, x in enumerate(instances) if
                   x.api_key == client_api_key]
        index = -1
        if len(indices) > 0:
            index = indices[0]
        if index > -1:
            # if we already have an instance, just reuse it. No need to open new connection
            if instances[index].agent.chosen_groups != groups:
                print("⚠️ New Groups requested, switching to new Chat..")
                config.set_value("groups", groups)
                instances[index].agent.chat_id = None
            elif force_new_session:
                print("⚠️ New Session Requested, switching to new Chat..")
                config.set_value("groups", groups)
                instances[index].agent.chat_id = None

            pgpt = instances[index].agent

        else:
            #otherwise connect via api-key
            config.set_value("groups", groups)
            pgpt = PrivateGPTAPI(config, client_api_key=client_api_key)
            # remember that we already have an instance for the api key
            instance = ChatInstance(client_api_key, pgpt)
            instances.append(instance)

        if pgpt.logged_in:
            response = pgpt.respond_with_context(request.messages, request.response_format, request.tools)
            if response is not None:
                if "answer" not in response:
                    response["answer"] = "No Response received"
            if response is None or ("answer" in response and response["answer"] == "error"):
                   pgpt.login()
        else:
            response = {
                "chatId": "0",
                "answer": "API Key not valid",
            }
    else:
        response = {
            "chatId": "0",
            "answer": "No Input given",
        }

    if request.stream:
        return StreamingResponse(
            _resp_async_generator(response, request), media_type="application/x-ndjson"
        )
    else:
        return _resp_sync(response, request)


# legacy completions API
@app.post("/completions")
async def completions(request: CompletionRequest):
    headers = getattr(request_context, "headers", {})
    client_api_key = str(headers['authorization']).split(" ")[1]
    groups = default_groups
    if request.groups:
        groups = request.groups
    print("Groups: " + str(groups))
    if request.prompt:

        #otherwise connect via api-key
        config.set_value("groups", groups)
        pgpt = PrivateGPTAPI(config, client_api_key=client_api_key)
        # remember that we already have an instance for the api key

        if pgpt.logged_in:
            response = pgpt.respond_with_context([Message(role="user", content=request.prompt)], request.response_format, request.tools)

            if "answer" not in response:
                response["answer"] = "No Response received"
            if "answer" in response and response["answer"] == "error":
                if pgpt.login():
                    pgpt.create_chat()
        else:
            response = {
                "chatId": "0",
                "answer": "API Key not valid",
            }
    else:
        response = {
            "chatId": "0",
            "answer": "No Input given",
        }

    if request.stream :
        return StreamingResponse(
            _resp_async_generator_completions(response, request), media_type="application/x-ndjson"
        )
    else:
        return _resp_sync_completions(response, request)



@app.get("/models")
def return_models():
    return {
        "object": "list",
        "data": models
    }


@app.get('/models/{model_id}')
async def get_model(model_id: str):
    filtered_entries = list(filter(lambda item: item["id"] == model_id, models))
    entry = filtered_entries[0] if filtered_entries else None
    print(entry)
    if entry is None:
            raise HTTPException(status_code=404, detail="Model not found")
    return entry


if __name__ == "__main__":
    api_ip = config.get("api_ip", "0.0.0.0")
    api_port = config.get("api_port", 8001)
    uvicorn.run(app, host=api_ip, port=int(api_port))




```

--------------------------------------------------------------------------------
/agents/ChatBotAgent/html/index.html:
--------------------------------------------------------------------------------

```html
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ChatBot Agent Interface</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            padding: 0;
            background-color: #f4f4f9;
        }
        .container {
            max-width: 600px;
            margin: 0 auto;
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            text-align: center; /* Zentriert den Inhalt */
        }
        .logo {
            display: block;
            margin: 0 auto 20px; /* Zentriert das Logo und fügt Abstand ein */
            width: 150px;
            height: auto;
        }
        h1 {
            text-align: center;
            color: #333;
        }
        textarea, select, input, button {
            width: 100%;
            margin: 10px 0;
            padding: 10px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-sizing: border-box;
        }
        button {
            background-color: #007BFF;
            color: white;
            border: none;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background-color: #0056b3;
        }
        .response-box {
            margin-top: 20px;
            padding: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #f9f9f9;
            white-space: pre-wrap;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- Logo einfügen -->
        <img src="Logo_light.svg" alt="Logo" class="logo">

        <h1>ChatBot Agent</h1>

        <form id="queryForm">
            <label for="question">Question:</label>
            <textarea id="question" rows="3" placeholder="Enter your question here..." required></textarea>

            <label for="language">Language:</label>
            <select id="language">
                <option value="en" selected>English</option>
                <option value="de">German</option>
            </select>

            <label for="groups">Groups (optional, separated by commas):</label>
            <input type="text" id="groups" placeholder="Example: Group1, Group2">

            <label>
                <input type="checkbox" id="usePublic" checked>
                Use general knowledge
            </label>

            <button type="submit">Send Request</button>
        </form>

        <div class="response-box" id="responseBox">
            The response will be displayed here...
        </div>
    </div>

    <script>
        const apiUrl = "http://127.0.0.1:5001/ask"; // URL der API
        const apiKey = "IhrSichererAPIKey123"; // API-Key

        document.getElementById("queryForm").addEventListener("submit", async function(event) {
            event.preventDefault();

            // Eingaben aus dem Formular abrufen
            const question = document.getElementById("question").value.trim();
            const language = document.getElementById("language").value;
            const groupsInput = document.getElementById("groups").value;
            const groups = groupsInput
                .split(",")
                .map(group => group.trim())
                .filter(group => group); // Leere Gruppen entfernen
            const usePublic = document.getElementById("usePublic").checked;

            if (!question) {
                alert("Please enter a question.");
                return;
            }

            // JSON-Body für die Anfrage erstellen
            const body = {
                question: question,
                usePublic: usePublic,
                groups: groups,
                language: language
            };

            // Anzeige der Anfrage im Response-Box (optional)
            document.getElementById("responseBox").textContent = "Sending request...";

            // Anfrage senden
            try {
                const response = await fetch(apiUrl, {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        "X-API-KEY": apiKey // Korrigierter Header
                    },
                    body: JSON.stringify(body)
                });

                if (response.ok) {
                    const data = await response.json();

                    // Extrahiere das 'answer'-Feld und entferne mögliche Anführungszeichen
                    let answer = data.answer || "";
                    if (answer.startsWith('"') && answer.endsWith('"')) {
                        answer = answer.substring(1, answer.length - 1);
                    }

                    // Optional: Entschlüsselung von Unicode-Zeichen
                    try {
                        answer = decodeURIComponent(escape(answer));
                    } catch (e) {
                        console.warn("Unicode decoding failed:", e);
                    }

                    // Anzeige der Antwort
                    document.getElementById("responseBox").textContent = answer;
                } else {
                    // Fehlerbehandlung bei HTTP-Fehlern
                    const errorText = await response.text();
                    document.getElementById("responseBox").textContent = `Error: ${response.status} ${response.statusText}\n${errorText}`;
                }
            } catch (error) {
                // Fehlerbehandlung bei Netzwerk- oder anderen Fehlern
                document.getElementById("responseBox").textContent = `Request failed: ${error.message}`;
            }
        });
    </script>
</body>
</html>
```

--------------------------------------------------------------------------------
/agents/ChatBotAgent/html/index_de.html:
--------------------------------------------------------------------------------

```html
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ChatBot Agent Interface</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            padding: 0;
            background-color: #f4f4f9;
        }
        .container {
            max-width: 600px;
            margin: 0 auto;
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            text-align: center; /* Zentriert den Inhalt */
        }
        .logo {
            display: block;
            margin: 0 auto 20px; /* Zentriert das Logo und fügt Abstand ein */
            width: 150px;
            height: auto;
        }
        h1 {
            text-align: center;
            color: #333;
        }
        textarea, select, input, button {
            width: 100%;
            margin: 10px 0;
            padding: 10px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-sizing: border-box;
        }
        button {
            background-color: #007BFF;
            color: white;
            border: none;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background-color: #0056b3;
        }
        .response-box {
            margin-top: 20px;
            padding: 15px;
            border: 1px solid #ccc;
            border-radius: 5px;
            background-color: #f9f9f9;
            white-space: pre-wrap;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- Logo einfügen -->
        <img src="Logo_light.svg" alt="Logo" class="logo">

        <h1>ChatBot Agent</h1>

        <form id="queryForm">
            <label for="question">Frage:</label>
            <textarea id="question" rows="3" placeholder="Geben Sie Ihre Frage ein..." required></textarea>

            <label for="language">Sprache:</label>
            <select id="language">
                <option value="de" selected>Deutsch</option>
                <option value="en">Englisch</option>
            </select>

            <label for="groups">Gruppen (optional, getrennt durch Kommas):</label>
            <input type="text" id="groups" placeholder="Beispiel: Gruppe1, Gruppe2">

            <label>
                <input type="checkbox" id="usePublic" checked>
                Öffentliche Daten verwenden
            </label>

            <button type="submit">Anfrage senden</button>
        </form>

        <div class="response-box" id="responseBox">
            Antwort wird hier angezeigt...
        </div>
    </div>

    <script>
        const apiUrl = "http://192.168.100.185:5001/ask"; // URL der API
        const apiKey = "IhrSichererAPIKey123"; // API-Key

        document.getElementById("queryForm").addEventListener("submit", async function(event) {
            event.preventDefault();

            // Eingaben aus dem Formular abrufen
            const question = document.getElementById("question").value.trim();
            const language = document.getElementById("language").value;
            const groupsInput = document.getElementById("groups").value;
            const groups = groupsInput
                .split(",")
                .map(group => group.trim())
                .filter(group => group); // Leere Gruppen entfernen
            const usePublic = document.getElementById("usePublic").checked;

            if (!question) {
                alert("Bitte geben Sie eine Frage ein.");
                return;
            }

            // JSON-Body für die Anfrage erstellen
            const body = {
                question: question,
                usePublic: usePublic,
                groups: groups,
                language: language
            };

            // Anzeige der Anfrage im Response-Box (optional)
            document.getElementById("responseBox").textContent = "Anfrage wird gesendet...";

            // Anfrage senden
            try {
                const response = await fetch(apiUrl, {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        "X-API-KEY": apiKey // Korrigierter Header
                    },
                    body: JSON.stringify(body)
                });

                if (response.ok) {
                    const data = await response.json();

                    // Extrahiere das 'answer'-Feld und entferne mögliche Anführungszeichen
                    let answer = data.answer || "";
                    if (answer.startsWith('"') && answer.endsWith('"')) {
                        answer = answer.substring(1, answer.length - 1);
                    }

                    // Optional: Entschlüsselung von Unicode-Zeichen
                    try {
                        answer = decodeURIComponent(escape(answer));
                    } catch (e) {
                        console.warn("Unicode-Entschlüsselung fehlgeschlagen:", e);
                    }

                    // Anzeige der Antwort
                    document.getElementById("responseBox").textContent = answer;
                } else {
                    // Fehlerbehandlung bei HTTP-Fehlern
                    const errorText = await response.text();
                    document.getElementById("responseBox").textContent = `Fehler: ${response.status} ${response.statusText}\n${errorText}`;
                }
            } catch (error) {
                // Fehlerbehandlung bei Netzwerk- oder anderen Fehlern
                document.getElementById("responseBox").textContent = `Fehler bei der Anfrage: ${error.message}`;
            }
        });
    </script>
</body>
</html>

```

--------------------------------------------------------------------------------
/clients/Java/3.3 mcp_edit_source/MCPEditSourceClient.java:
--------------------------------------------------------------------------------

```java
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MCPEditSourceClient {

    public static void main(String[] args) {
        // Mindestens 8 Strings im Array erforderlich, z.B.:
        // --server-ip 127.0.0.1 --server-port 1234 --token X --source-id Y
        // plus optionale: --title "..." --content "..." --groups ...
        if (args.length < 8) {
            printUsage();
            return;
        }

        // Argumente einlesen
        String serverIp   = getArgument(args, "--server-ip");
        String portStr    = getArgument(args, "--server-port");
        String token      = getArgument(args, "--token");
        String sourceId   = getArgument(args, "--source-id");
        String title      = getArgument(args, "--title");
        String content    = getArgument(args, "--content");
        List<String> groups = getListArgument(args, "--groups");

        // Prüfung auf null
        if (serverIp == null || portStr == null || token == null || sourceId == null) {
            System.out.println("Fehler: Mindestens eines der Pflichtargumente fehlt.");
            return;
        }

        // Port in int umwandeln
        int serverPort;
        try {
            serverPort = Integer.parseInt(portStr);
        } catch (NumberFormatException e) {
            System.out.println("Fehler: --server-port muss eine ganzzahlige Portangabe sein.");
            return;
        }

        System.out.println("📤 Sende Anfrage zum Editieren einer Quelle...");

        // Anfrage an den Server senden
        String response = sendEditSourceRequest(serverIp, serverPort, token, sourceId, title, content, groups);

        // Antwort ausgeben
        System.out.println("Response from server:");
        System.out.println(response);
    }

    /**
     * Baut die Payload für die "edit_source"-Anfrage zusammen und sendet sie über TCP.
     */
    private static String sendEditSourceRequest(
            String serverIp,
            int serverPort,
            String token,
            String sourceId,
            String title,
            String content,
            List<String> groups
    ) {
        // Arguments-Objekt erstellen
        JSONObject arguments = new JSONObject();
        arguments.put("sourceId", sourceId);

        if (title != null && !title.trim().isEmpty()) {
            arguments.put("title", title);
        }

        if (content != null && !content.trim().isEmpty()) {
            arguments.put("content", content);
        }

        // Gruppen (falls keine übergeben, bleibt es einfach eine leere Liste)
        if (groups == null) {
            groups = new ArrayList<>();
        }
        JSONArray groupsArray = new JSONArray(groups);
        arguments.put("groups", groupsArray);

        // Gesamte Payload
        JSONObject payload = new JSONObject();
        payload.put("command", "edit_source");
        payload.put("token", token);
        payload.put("arguments", arguments);

        // JSON in String umwandeln
        String payloadJson = payload.toString();

        // TCP-Verbindung aufbauen und senden
        try (Socket client = new Socket(serverIp, serverPort)) {
            // Senden
            OutputStream out = client.getOutputStream();
            byte[] data = payloadJson.getBytes(StandardCharsets.UTF_8);
            out.write(data);
            out.flush();

            // Antwort empfangen
            InputStream in = client.getInputStream();
            byte[] buffer = new byte[4096];
            StringBuilder responseBuilder = new StringBuilder();

            int bytesRead;
            do {
                bytesRead = in.read(buffer);
                if (bytesRead > 0) {
                    responseBuilder.append(new String(buffer, 0, bytesRead, StandardCharsets.UTF_8));
                }
            } while (bytesRead == buffer.length);

            return responseBuilder.toString();

        } catch (IOException e) {
            return "Error: " + e.getMessage();
        }
    }

    /**
     * Liest den Wert für ein bestimmtes Argument aus (z.B. --server-ip 127.0.0.1).
     */
    private static String getArgument(String[] args, String key) {
        for (int i = 0; i < args.length - 1; i++) {
            if (args[i].equals(key)) {
                return args[i + 1];
            }
        }
        return null;
    }

    /**
     * Liest eine Liste von Werten aus (z.B. --groups G1 G2 G3 ...), bis zum nächsten -- oder Ende.
     */
    private static List<String> getListArgument(String[] args, String key) {
        List<String> result = new ArrayList<>();
        for (int i = 0; i < args.length; i++) {
            if (args[i].equals(key)) {
                // Ab hier Werte einsammeln
                for (int j = i + 1; j < args.length; j++) {
                    if (args[j].startsWith("--")) {
                        break;
                    }
                    result.add(args[j]);
                }
                break;
            }
        }
        return result;
    }

    private static void printUsage() {
        System.out.println("Usage:");
        System.out.println("  --server-ip <IP> --server-port <PORT> --token <TOKEN> --source-id <SOURCE_ID>");
        System.out.println("  [--title <TITLE>] [--content <CONTENT>] [--groups <LIST_OF_GROUPS>]");
        System.out.println();
        System.out.println("Example:");
        System.out.println("  java -cp .;json-20241224.jar MCPEditSourceClient \\");
        System.out.println("       --server-ip 127.0.0.1 --server-port 1234 --token SomeToken --source-id 456 \\");
        System.out.println("       --title \"Neuer Titel\" --content \"Neuer Inhalt...\" --groups DevOps Finance");
    }
}

```

--------------------------------------------------------------------------------
/clients/PHP/9.0 mcp_keygen/MCPKeygenClient.php:
--------------------------------------------------------------------------------

```php
<?php
/**
 * MCPKeygenClient.php
 *
 * A PHP script that acts as a Keygen Client. It connects to a server via TCP,
 * sends a keygen request, and receives the server's response.
 *
 * Usage:
 * php MCPKeygenClient.php --server-ip <IP> --server-port <Port> --token <Token> --password <Password>
 */

/**
 * Function to parse command line arguments
 *
 * @param array $args The command line arguments
 * @return array An associative array with the parsed arguments
 */
function parseArguments($args) {
    $parsedArgs = [];
    $argc = count($args);
    for ($i = 1; $i < $argc; $i++) {
        switch ($args[$i]) {
            case '--server-ip':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverIp'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --server-ip.\n");
                }
                break;
            case '--server-port':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverPort'] = intval($args[++$i]);
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --server-port.\n");
                }
                break;
            case '--token':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['token'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --token.\n");
                }
                break;
            case '--password':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['password'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --password.\n");
                }
                break;
            default:
                fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
        }
    }
    return $parsedArgs;
}

/**
 * Helper function to check if a string starts with a specific prefix
 *
 * @param string $string The string to check
 * @param string $prefix The prefix
 * @return bool True if the string starts with the prefix, otherwise False
 */
function startsWith($string, $prefix) {
    return substr($string, 0, strlen($prefix)) === $prefix;
}

/**
 * Function to send a Keygen request over a TCP connection
 *
 * @param string $serverIp The server's IP address
 * @param int $serverPort The server's port
 * @param string $token The authentication token
 * @param string $password The password for key generation
 * @return array The response received from the server as an associative array
 * @throws Exception On connection errors or JSON parsing errors
 */
function sendKeygenRequest($serverIp, $serverPort, $token, $password) {
    $payload = [
        "command" => "keygen",
        "token" => $token,
        "arguments" => [
            "password" => $password
        ]
    ];

    $jsonPayload = json_encode($payload);
    if ($jsonPayload === false) {
        throw new Exception("Error encoding JSON payload: " . json_last_error_msg());
    }

    $errno = 0;
    $errstr = '';
    $timeoutDuration = 10; // Seconds (10 seconds timeout)
    $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);

    if (!$client) {
        throw new Exception("Connection error: $errstr ($errno)");
    }

    echo "🔗 Connected to server ({$serverIp}:{$serverPort}).\n";
    echo "📤 Sending Payload: {$jsonPayload}\n";

    fwrite($client, $jsonPayload);

    $responseData = '';
    stream_set_timeout($client, $timeoutDuration);

    while (!feof($client)) {
        $data = fread($client, 1024);
        if ($data === false) {
            throw new Exception("Error reading data from server.");
        }
        if ($data === '') {
            break; // No more data
        }
        echo "📥 Received data: {$data}\n";
        $responseData .= $data;

        // Attempt to parse the received data as JSON
        $parsedData = json_decode($responseData, true);
        if ($parsedData !== null) {
            echo "✅ JSON response successfully parsed.\n";
            fclose($client);
            return $parsedData;
        }

        // Check if the stream has timed out
        $info = stream_get_meta_data($client);
        if ($info['timed_out']) {
            throw new Exception("Timeout while waiting for data from server.");
        }
    }

    fclose($client);
    throw new Exception("Connection to server was closed before a complete response was received.");
}

/**
 * Main function of the script
 */
function main($argv) {
    $parsedArgs = parseArguments($argv);
    $serverIp = $parsedArgs['serverIp'] ?? null;
    $serverPort = $parsedArgs['serverPort'] ?? null;
    $token = $parsedArgs['token'] ?? null;
    $password = $parsedArgs['password'] ?? null;

    // Check if all required parameters are present
    if (!$serverIp || !$serverPort || !$token || !$password) {
        fwrite(STDERR, "❌ Error: --server-ip, --server-port, --token, and --password are required.\n");
        fwrite(STDOUT, "📖 Usage: php MCPKeygenClient.php --server-ip <IP> --server-port <Port> --token <Token> --password <Password>\n");
        exit(1);
    }

    try {
        echo "🔑 Sending Keygen request...\n";
        $response = sendKeygenRequest(
            $serverIp,
            $serverPort,
            $token,
            $password
        );
        echo "✔️ Server response:\n";
        echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    } catch (Exception $e) {
        fwrite(STDERR, "❌ Error during Keygen request: " . $e->getMessage() . "\n");
    }
}

// Check if PHP version is at least 7.1 (for better features)
if (version_compare(PHP_VERSION, '7.1.0') < 0) {
    fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
    exit(1);
}

// Call the main function
main($argv);
?>

```

--------------------------------------------------------------------------------
/clients/JavaScript/5.2 mcp_delete_user/MCPDeleteUserClient.js:
--------------------------------------------------------------------------------

```javascript
<?php
/**
 * MCPDeleteUserClient.php
 *
 * A PHP script that acts as a Delete User Client. It connects to a server via TCP,
 * sends a request to delete an existing user, and receives the server's response.
 *
 * Usage:
 * php MCPDeleteUserClient.php --server-ip <IP> --server-port <Port> --email <Email> --token <Token>
 */

/**
 * Function to parse command line arguments
 *
 * @param array $args Array of command line arguments
 * @return array Associative array with parsed arguments
 */
function parseArguments($args) {
    $parsedArgs = [];
    $argc = count($args);
    for ($i = 1; $i < $argc; $i++) {
        switch ($args[$i]) {
            case '--server-ip':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverIp'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --server-ip.\n");
                }
                break;
            case '--server-port':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverPort'] = intval($args[++$i]);
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --server-port.\n");
                }
                break;
            case '--email':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['email'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --email.\n");
                }
                break;
            case '--token':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['token'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --token.\n");
                }
                break;
            default:
                fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
        }
    }
    return $parsedArgs;
}

/**
 * Helper function to check if a string starts with a specific prefix
 *
 * @param string $string The string to check
 * @param string $prefix The prefix
 * @return bool True if the string starts with the prefix, otherwise False
 */
function startsWith($string, $prefix) {
    return substr($string, 0, strlen($prefix)) === $prefix;
}

/**
 * Function to send a Delete User request over a TCP connection
 *
 * @param string $serverIp The server's IP address
 * @param int $serverPort The server's port
 * @param string $email The email of the user to be deleted
 * @param string $token The authentication token
 * @return array The response received from the server as an associative array
 * @throws Exception On connection errors or JSON parsing errors
 */
function sendDeleteUserRequest($serverIp, $serverPort, $email, $token) {
    $payload = [
        "command" => "delete_user",
        "token" => $token,
        "arguments" => [
            "email" => $email
        ]
    ];

    $jsonPayload = json_encode($payload);
    if ($jsonPayload === false) {
        throw new Exception("Error while encoding the JSON payload: " . json_last_error_msg());
    }

    $errno = 0;
    $errstr = '';
    $timeoutDuration = 10; // Seconds (10 seconds timeout)
    $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);

    if (!$client) {
        throw new Exception("Connection error: $errstr ($errno)");
    }

    echo "🔗 Connected to server ({$serverIp}:{$serverPort}).\n";
    echo "📤 Sending Payload: {$jsonPayload}\n";

    fwrite($client, $jsonPayload);

    $responseData = '';
    stream_set_timeout($client, $timeoutDuration);

    while (!feof($client)) {
        $data = fread($client, 1024);
        if ($data === false) {
            throw new Exception("Error reading data from server.");
        }
        if ($data === '') {
            break; // No more data
        }
        echo "📥 Received data: {$data}\n";
        $responseData .= $data;

        // Attempt to parse the received data as JSON
        $parsedData = json_decode($responseData, true);
        if ($parsedData !== null) {
            echo "✅ JSON response successfully parsed.\n";
            fclose($client);
            return $parsedData;
        }

        // Check if the stream has timed out
        $info = stream_get_meta_data($client);
        if ($info['timed_out']) {
            throw new Exception("Timeout while waiting for data from server.");
        }
    }

    fclose($client);
    throw new Exception("Connection to server was closed before a complete response was received.");
}

/**
 * Main function of the script
 */
function main($argv) {
    $parsedArgs = parseArguments($argv);
    $serverIp = $parsedArgs['serverIp'] ?? null;
    $serverPort = $parsedArgs['serverPort'] ?? null;
    $email = $parsedArgs['email'] ?? null;
    $token = $parsedArgs['token'] ?? null;

    // Check if all required parameters are present
    if (!$serverIp || !$serverPort || !$email || !$token) {
        fwrite(STDERR, "❌ ERROR: --server-ip, --server-port, --email, and --token are required.\n");
        fwrite(STDOUT, "📖 Example: php MCPDeleteUserClient.php --server-ip 192.168.0.1 --server-port 5000 --email [email protected] --token YOUR_AUTH_TOKEN\n");
        exit(1);
    }

    try {
        echo "🗑️ Sending Delete-User request...\n";
        $response = sendDeleteUserRequest(
            $serverIp,
            $serverPort,
            $email,
            $token
        );
        echo "✔️ Server response:\n";
        echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    } catch (Exception $e) {
        fwrite(STDERR, "❌ Error deleting user: " . $e->getMessage() . "\n");
    }
}

// Check if PHP version is at least 7.1 (for better features)
if (version_compare(PHP_VERSION, '7.1.0') < 0) {
    fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
    exit(1);
}

// Call the main function
main($argv);
?>

```

--------------------------------------------------------------------------------
/clients/PHP/5.2 mcp_delete_user/MCPDeleteUserClient.php:
--------------------------------------------------------------------------------

```php
<?php
/**
 * MCPDeleteUserClient.php
 *
 * A PHP script that acts as a Delete User Client. It connects to a server via TCP,
 * sends a request to delete an existing user, and receives the server's response.
 *
 * Usage:
 * php MCPDeleteUserClient.php --server-ip <IP> --server-port <Port> --email <Email> --token <Token>
 */

/**
 * Function to parse command line arguments
 *
 * @param array $args Array of command line arguments
 * @return array Associative array with parsed arguments
 */
function parseArguments($args) {
    $parsedArgs = [];
    $argc = count($args);
    for ($i = 1; $i < $argc; $i++) {
        switch ($args[$i]) {
            case '--server-ip':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverIp'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --server-ip.\n");
                }
                break;
            case '--server-port':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverPort'] = intval($args[++$i]);
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --server-port.\n");
                }
                break;
            case '--email':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['email'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --email.\n");
                }
                break;
            case '--token':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['token'] = $args[++$i];
                } else {
                    fwrite(STDERR, "⚠️ Warning: No value provided for --token.\n");
                }
                break;
            default:
                fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
        }
    }
    return $parsedArgs;
}

/**
 * Helper function to check if a string starts with a specific prefix
 *
 * @param string $string The string to check
 * @param string $prefix The prefix
 * @return bool True if the string starts with the prefix, otherwise False
 */
function startsWith($string, $prefix) {
    return substr($string, 0, strlen($prefix)) === $prefix;
}

/**
 * Function to send a Delete User request over a TCP connection
 *
 * @param string $serverIp The server's IP address
 * @param int $serverPort The server's port
 * @param string $email The email of the user to be deleted
 * @param string $token The authentication token
 * @return array The response received from the server as an associative array
 * @throws Exception On connection errors or JSON parsing errors
 */
function sendDeleteUserRequest($serverIp, $serverPort, $email, $token) {
    $payload = [
        "command" => "delete_user",
        "token" => $token,
        "arguments" => [
            "email" => $email
        ]
    ];

    $jsonPayload = json_encode($payload);
    if ($jsonPayload === false) {
        throw new Exception("Error while encoding the JSON payload: " . json_last_error_msg());
    }

    $errno = 0;
    $errstr = '';
    $timeoutDuration = 10; // Seconds (10 seconds timeout)
    $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);

    if (!$client) {
        throw new Exception("Connection error: $errstr ($errno)");
    }

    echo "🔗 Connected to server ({$serverIp}:{$serverPort}).\n";
    echo "📤 Sending Payload: {$jsonPayload}\n";

    fwrite($client, $jsonPayload);

    $responseData = '';
    stream_set_timeout($client, $timeoutDuration);

    while (!feof($client)) {
        $data = fread($client, 1024);
        if ($data === false) {
            throw new Exception("Error reading data from server.");
        }
        if ($data === '') {
            break; // No more data
        }
        echo "📥 Received data: {$data}\n";
        $responseData .= $data;

        // Attempt to parse the received data as JSON
        $parsedData = json_decode($responseData, true);
        if ($parsedData !== null) {
            echo "✅ JSON response successfully parsed.\n";
            fclose($client);
            return $parsedData;
        }

        // Check if the stream has timed out
        $info = stream_get_meta_data($client);
        if ($info['timed_out']) {
            throw new Exception("Timeout while waiting for data from server.");
        }
    }

    fclose($client);
    throw new Exception("Connection to server was closed before a complete response was received.");
}

/**
 * Main function of the script
 */
function main($argv) {
    $parsedArgs = parseArguments($argv);
    $serverIp = $parsedArgs['serverIp'] ?? null;
    $serverPort = $parsedArgs['serverPort'] ?? null;
    $email = $parsedArgs['email'] ?? null;
    $token = $parsedArgs['token'] ?? null;

    // Check if all required parameters are present
    if (!$serverIp || !$serverPort || !$email || !$token) {
        fwrite(STDERR, "❌ ERROR: --server-ip, --server-port, --email, and --token are required.\n");
        fwrite(STDOUT, "📖 Example: php MCPDeleteUserClient.php --server-ip 192.168.0.1 --server-port 5000 --email [email protected] --token YOUR_AUTH_TOKEN\n");
        exit(1);
    }

    try {
        echo "🗑️ Sending Delete-User request...\n";
        $response = sendDeleteUserRequest(
            $serverIp,
            $serverPort,
            $email,
            $token
        );
        echo "✔️ Server response:\n";
        echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    } catch (Exception $e) {
        fwrite(STDERR, "❌ Error deleting user: " . $e->getMessage() . "\n");
    }
}

// Check if PHP version is at least 7.1 (for better features)
if (version_compare(PHP_VERSION, '7.1.0') < 0) {
    fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
    exit(1);
}

// Call the main function
main($argv);
?>

```

--------------------------------------------------------------------------------
/agents/AgentInterface/Python/network.py:
--------------------------------------------------------------------------------

```python
import socket
import ssl
import json
import logging
import time
from .language import languages

class NetworkError(Exception):
    pass

class NetworkClient:
    def __init__(
        self, server_ip, server_port, language="en",
        retries=3, delay=5, use_ssl=True, accept_self_signed=True
    ):
        self.server_ip = server_ip
        self.server_port = server_port
        self.retries = retries
        self.delay = delay
        self.use_ssl = use_ssl
        self.accept_self_signed = accept_self_signed
        self.language = language if language in languages else "en"
        self.lang = languages[self.language]

    def get_lang_message(self, key, **kwargs):
        """
        Secure method to retrieve messages from the language dictionary.
        Returns a default message if the key does not exist.
        """
        message = self.lang.get(key, "Message not defined.")
        utf8_encoded_string = bytes(message, 'utf-8')
        message = str(utf8_encoded_string, 'utf-8')
        try:
            return message.format(**kwargs)
        except KeyError as e:
            logging.error(f"Missing placeholder in language file for key '{key}': {e}")
            return message

    def send_request(self, payload):
        payload_json = json.dumps(payload)
        #logging.info(f"Prepared payload: {payload_json}")

        for attempt in range(1, self.retries + 1):
            client_socket = None
            try:
                raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                raw_socket.settimeout(30)
                
                logging.info(
                    self.get_lang_message(
                        "connecting_to_server",
                        ip=self.server_ip,
                        port=self.server_port,
                        attempt=attempt,
                        retries=self.retries
                    )
                )
                
                # SSL/TLS initialisieren (falls gewünscht)
                if self.use_ssl:
                    context = ssl.create_default_context()
                    if self.accept_self_signed:
                        context.check_hostname = False
                        context.verify_mode = ssl.CERT_NONE
                    client_socket = context.wrap_socket(raw_socket, server_hostname=self.server_ip)
                else:
                    client_socket = raw_socket
                
                # Verbinden
                client_socket.connect((self.server_ip, self.server_port))
                logging.info(self.get_lang_message("connection_established"))
                
                # Anfrage senden
                #logging.info(
                #    self.get_lang_message(
                #        "sending_payload",
                #        payload=payload_json
                #    )
                #)
                client_socket.sendall((payload_json + '\n').encode("utf-8"))
                
                # Alle Daten empfangen, bis Server von sich aus schließt oder Timeout
                response = b""
                while True:
                    try:
                        part = client_socket.recv(4096)
                        if not part:
                            # Keine Daten mehr -> Server hat Verbindung geschlossen
                            break
                        response += part
                    except socket.timeout:
                        # Wenn wir hier sicher sind, dass keine weiteren Daten mehr kommen,
                        # kann man das Lesen beenden. Oder retry. Je nach Protokoll.
                        logging.warning(self.get_lang_message("connection_timed_out"))
                        break
                
                decoded = response.decode("utf-8").strip()
                #logging.info(f"Received response: {decoded}")
                
                if not decoded:
                    raise ValueError("Empty response received")

                # JSON parsen
                try:
                    parsed_response = json.loads(decoded)
                    logging.info(
                        self.get_lang_message("formatted_response"),
                        extra={"data": parsed_response}
                    )
                    
                    if "data" in parsed_response and "personalGroups" in parsed_response["data"]:
                        personal_groups = parsed_response["data"]["personalGroups"]
                        logging.info(
                            self.get_lang_message("personal_groups_received", groups=personal_groups)
                        )
                    
                    # Erfolgreich -> Socket normal schließen und Ergebnis zurückgeben
                    client_socket.close()
                    return parsed_response

                except json.JSONDecodeError:
                    logging.error(self.get_lang_message("invalid_json_response"))
                    raise NetworkError(self.get_lang_message("invalid_json_response"))
            
            except socket.timeout:
                logging.warning(self.get_lang_message("connection_timed_out"))
            except Exception as e:
                logging.error(
                    self.get_lang_message(
                        "connection_error",
                        error=str(e)
                    )
                )
            
            # Bei Misserfolg (und wenn noch Versuche übrig): warten, neu versuchen
            if attempt < self.retries:
                logging.info(
                    self.get_lang_message(
                        "retrying_in_seconds",
                        delay=self.delay
                    )
                )
                time.sleep(self.delay)
            
            # Socket schließen (wenn noch offen), kein shutdown(SHUT_RDWR) verwenden
            if client_socket is not None:
                try:
                    client_socket.close()
                except:
                    pass
        
        # Nach allen Versuchen fehlgeschlagen
        logging.error(self.get_lang_message("all_retries_failed"))
        raise NetworkError(self.get_lang_message("all_retries_failed"))

```

--------------------------------------------------------------------------------
/clients/PHP/4.0 mcp_list_groups/MCPListGroupsClient.php:
--------------------------------------------------------------------------------

```php
<?php
/**
 * MCPListGroupsClient.php
 *
 * A PHP script acting as a List Groups Client. It connects to a server via TCP,
 * sends a request to list groups, and receives the server's response.
 *
 * Usage:
 * php MCPListGroupsClient.php --server-ip <IP> --server-port <Port> --token <Token>
 */

/**
 * Function to parse command line arguments
 *
 * @param array $args Command line arguments
 * @return array Associative array of parsed arguments
 */
function parseArguments($args) {
    $parsedArgs = [];
    $argc = count($args);
    for ($i = 1; $i < $argc; $i++) {
        switch ($args[$i]) {
            case '--server-ip':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverIp'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --server-ip expects a value.\n");
                    exit(1);
                }
                break;
            case '--server-port':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['serverPort'] = intval($args[++$i]);
                } else {
                    fwrite(STDERR, "Error: --server-port expects a value.\n");
                    exit(1);
                }
                break;
            case '--token':
                if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
                    $parsedArgs['token'] = $args[++$i];
                } else {
                    fwrite(STDERR, "Error: --token expects a value.\n");
                    exit(1);
                }
                break;
            default:
                fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
        }
    }
    return $parsedArgs;
}

/**
 * Helper function to check if a string starts with a specific prefix
 *
 * @param string $string The string to check
 * @param string $prefix The prefix
 * @return bool True if the string starts with the prefix, otherwise False
 */
function startsWith($string, $prefix) {
    return substr($string, 0, strlen($prefix)) === $prefix;
}

/**
 * Function for interactively prompting a parameter (optional)
 *
 * @param string $prompt The prompt message
 * @return string User input
 */
function askQuestionPrompt($prompt) {
    if (preg_match('/^win/i', PHP_OS)) {
        $vbscript = sys_get_temp_dir() . 'prompt_input.vbs';
        file_put_contents($vbscript, 'wscript.echo(InputBox("' . addslashes($prompt) . '", "", ""))');
        $response = shell_exec("cscript //nologo " . escapeshellarg($vbscript));
        unlink($vbscript);
        return trim($response);
    } else {
        echo $prompt;
        $handle = fopen("php://stdin", "r");
        $response = trim(fgets($handle));
        fclose($handle);
        return $response;
    }
}

/**
 * Function to send a generic request over a TCP connection
 *
 * @param string $serverIp The server's IP address
 * @param int $serverPort The server's port
 * @param array $payload The payload to send as an associative array
 * @return array The response received from the server as an associative array
 * @throws Exception On connection errors or JSON parsing errors
 */
function sendRequest($serverIp, $serverPort, $payload) {
    $jsonPayload = json_encode($payload);
    if ($jsonPayload === false) {
        throw new Exception("Error while coding the JSON payload: " . json_last_error_msg());
    }

    $errno = 0;
    $errstr = '';
    $timeoutDuration = 10; // Seconds
    $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);
    
    if (!$client) {
        throw new Exception("Connection error: $errstr ($errno)");
    }

    echo "🔗 Connected to the server ({$serverIp}:{$serverPort}).\n";
    echo "📤 Sending payload: $jsonPayload\n";

    fwrite($client, $jsonPayload);

    $responseData = '';
    stream_set_timeout($client, $timeoutDuration);

    while (!feof($client)) {
        $data = fread($client, 1024);
        if ($data === false) {
            throw new Exception("Error reading data from the server.");
        }
        if ($data === '') {
            break; // No more data
        }
        echo "📥 Received data: $data\n";
        $responseData .= $data;

        $parsedData = json_decode($responseData, true);
        if ($parsedData !== null) {
            echo "✅ JSON response successfully parsed.\n";
            fclose($client);
            return $parsedData;
        }

        $info = stream_get_meta_data($client);
        if ($info['timed_out']) {
            throw new Exception("Timeout waiting for data from the server.");
        }
    }

    fclose($client);
    throw new Exception("Connection to the server was closed before a complete response was received.");
}

/**
 * Main function of the script
 */
function main($argv) {
    $parsedArgs = parseArguments($argv);
    $serverIp = $parsedArgs['serverIp'] ?? null;
    $serverPort = $parsedArgs['serverPort'] ?? null;
    $token = $parsedArgs['token'] ?? null;

    if (!$serverIp) {
        $serverIp = askQuestionPrompt('🔗 Please enter the server IP: ');
    }
    if (!$serverPort) {
        $portInput = askQuestionPrompt('🔗 Please enter the server port: ');
        $serverPort = intval($portInput);
        if ($serverPort <= 0) {
            fwrite(STDERR, "❌ ERROR: Invalid server port.\n");
            exit(1);
        }
    }
    if (!$token) {
        $token = askQuestionPrompt('🔒 Please enter your authentication token: ');
    }

    if (!$serverIp || !$serverPort || !$token) {
        fwrite(STDERR, "❌ ERROR: Missing required parameters.\n");
        fwrite(STDOUT, "Usage: php MCPListGroupsClient.php --server-ip <IP> --server-port <Port> --token <Token>\n");
        exit(1);
    }

    $payload = [
        "command" => "list_groups",
        "token" => $token
    ];

    try {
        echo "📄 Retrieving groups...\n";
        $response = sendRequest($serverIp, $serverPort, $payload);
        echo "✔️ Response:\n";
        echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
    } catch (Exception $e) {
        fwrite(STDERR, "❌ ERROR: " . $e->getMessage() . "\n");
    }
}

if (version_compare(PHP_VERSION, '7.1.0') < 0) {
    fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
    exit(1);
}

main($argv);
?>

```
Page 8/16FirstPrevNextLast