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

# Directory Structure

```
├── .gitattributes
├── .gitignore
├── agents
│   ├── __init__.py
│   ├── AgentInterface
│   │   ├── __init__.py
│   │   ├── Python
│   │   │   ├── __init__.py
│   │   │   ├── agent.py
│   │   │   ├── color.py
│   │   │   ├── config.py
│   │   │   ├── language.py
│   │   │   ├── local_file_handler.py
│   │   │   └── network.py
│   │   └── requirements.txt
│   ├── AgentMonitoring
│   │   ├── ChatBot-Agent Dashboard Example - Grafana.json
│   │   ├── images
│   │   │   ├── Grafana.png
│   │   │   └── Prometheus.png
│   │   ├── IoT-Agent Dashboard Example - Grafana.json
│   │   ├── OpenAI compatible API - Agent Dashboard Example - Grafana.json
│   │   ├── prometheus Example.yml
│   │   └── README.md
│   ├── ChatBotAgent
│   │   ├── __init__.py
│   │   ├── config.json.example
│   │   ├── html
│   │   │   ├── favicon.ico
│   │   │   ├── index_de.html
│   │   │   ├── index.html
│   │   │   ├── Logo_light.svg
│   │   │   ├── start_http_server.ps1
│   │   │   └── start_http_server.sh
│   │   ├── Python
│   │   │   ├── __init__.py
│   │   │   └── chatbot_agent.py
│   │   ├── README.md
│   │   └── requirements.txt
│   ├── IoTAgent
│   │   ├── config_example.json
│   │   ├── Python
│   │   │   ├── iot_mqtt_agent.py
│   │   │   └── language.py
│   │   ├── README.md
│   │   └── requirements.txt
│   ├── 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/C++/5.1 mcp_edit_user/MCPEditUserClient.cpp:
--------------------------------------------------------------------------------

```cpp
  1 | #include <iostream>
  2 | #include <string>
  3 | #include <map>
  4 | #include <vector>
  5 | #include <sstream>
  6 | #include <stdexcept>
  7 | #include <json/json.h>
  8 | #include <winsock2.h>
  9 | #include <ws2tcpip.h>
 10 | 
 11 | #pragma comment(lib, "ws2_32.lib") // Verlinkung mit der Winsock-Bibliothek
 12 | 
 13 | // Funktion zum Parsen von Argumenten
 14 | std::map<std::string, std::string> parseArguments(int argc, char* argv[]) {
 15 |     std::map<std::string, std::string> args;
 16 |     for (int i = 1; i < argc; ++i) {
 17 |         std::string key = argv[i];
 18 |         if (i + 1 < argc && key.rfind("--", 0) == 0) {
 19 |             args[key] = argv[++i];
 20 |         }
 21 |     }
 22 |     return args;
 23 | }
 24 | 
 25 | // Funktion zum Parsen von Listen-Argumenten
 26 | std::vector<std::string> parseListArgument(int argc, char* argv[], const std::string& key) {
 27 |     std::vector<std::string> values;
 28 |     for (int i = 1; i < argc; ++i) {
 29 |         if (argv[i] == key && i + 1 < argc) {
 30 |             for (int j = i + 1; j < argc && std::string(argv[j]).rfind("--", 0) != 0; ++j) {
 31 |                 values.push_back(argv[j]);
 32 |             }
 33 |         }
 34 |     }
 35 |     return values;
 36 | }
 37 | 
 38 | // Funktion zum Senden der Anfrage
 39 | std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) {
 40 |     Json::StreamWriterBuilder writer;
 41 |     std::string payloadJson = Json::writeString(writer, payload);
 42 | 
 43 |     // Winsock initialisieren
 44 |     WSADATA wsaData;
 45 |     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
 46 |         throw std::runtime_error("Failed to initialize Winsock.");
 47 |     }
 48 | 
 49 |     // Socket erstellen
 50 |     SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
 51 |     if (sock == INVALID_SOCKET) {
 52 |         WSACleanup();
 53 |         throw std::runtime_error("Failed to create socket.");
 54 |     }
 55 | 
 56 |     // Server-Adresse konfigurieren
 57 |     sockaddr_in serverAddr;
 58 |     serverAddr.sin_family = AF_INET;
 59 |     serverAddr.sin_port = htons(serverPort);
 60 |     if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) {
 61 |         closesocket(sock);
 62 |         WSACleanup();
 63 |         throw std::runtime_error("Invalid server IP address.");
 64 |     }
 65 | 
 66 |     // Verbindung herstellen
 67 |     if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
 68 |         closesocket(sock);
 69 |         WSACleanup();
 70 |         throw std::runtime_error("Connection failed.");
 71 |     }
 72 | 
 73 |     // Daten senden
 74 |     if (send(sock, payloadJson.c_str(), payloadJson.size(), 0) < 0) {
 75 |         closesocket(sock);
 76 |         WSACleanup();
 77 |         throw std::runtime_error("Failed to send data.");
 78 |     }
 79 | 
 80 |     // Antwort empfangen
 81 |     char buffer[4096];
 82 |     int bytesRead;
 83 |     std::ostringstream response;
 84 | 
 85 |     do {
 86 |         bytesRead = recv(sock, buffer, sizeof(buffer) - 1, 0);
 87 |         if (bytesRead > 0) {
 88 |             buffer[bytesRead] = '\0'; // Null-terminieren
 89 |             response << buffer;
 90 |         }
 91 |     } while (bytesRead == sizeof(buffer) - 1);
 92 | 
 93 |     // Socket schließen
 94 |     closesocket(sock);
 95 |     WSACleanup();
 96 | 
 97 |     return response.str();
 98 | }
 99 | 
100 | int main(int argc, char* argv[]) {
101 |     try {
102 |         auto args = parseArguments(argc, argv);
103 | 
104 |         // Pflichtargumente überprüfen
105 |         if (args["--server-ip"].empty() || args["--server-port"].empty() || args["--token"].empty() || args["--email"].empty() || args["--name"].empty()) {
106 |             std::cerr << "Usage: --server-ip <IP> --server-port <PORT> --token <TOKEN> --email <EMAIL> --name <NAME> [optional parameters]\n";
107 |             return 1;
108 |         }
109 | 
110 |         // Argumente auslesen
111 |         std::string serverIp = args["--server-ip"];
112 |         int serverPort = std::stoi(args["--server-port"]);
113 |         std::string token = args["--token"];
114 |         std::string email = args["--email"];
115 |         std::string name = args["--name"];
116 |         std::string language = args.count("--language") ? args["--language"] : "en";
117 |         std::string timezone = args.count("--timezone") ? args["--timezone"] : "UTC";
118 |         std::string password = args["--password"];
119 |         bool publicUpload = args.count("--publicUpload") > 0;
120 |         auto groups = parseListArgument(argc, argv, "--groups");
121 |         auto roles = parseListArgument(argc, argv, "--roles");
122 |         bool activateFtp = args.count("--activateFtp") > 0;
123 |         std::string ftpPassword = args["--ftpPassword"];
124 | 
125 |         // JSON-Payload erstellen
126 |         Json::Value payload;
127 |         payload["command"] = "edit_user";
128 |         payload["token"] = token;
129 |         payload["arguments"]["email"] = email;
130 |         payload["arguments"]["name"] = name;
131 |         payload["arguments"]["language"] = language;
132 |         payload["arguments"]["timezone"] = timezone;
133 |         if (!password.empty()) payload["arguments"]["password"] = password;
134 |         payload["arguments"]["publicUpload"] = publicUpload;
135 |         for (const auto& group : groups) {
136 |             payload["arguments"]["groups"].append(group);
137 |         }
138 |         for (const auto& role : roles) {
139 |             payload["arguments"]["roles"].append(role);
140 |         }
141 |         payload["arguments"]["activateFtp"] = activateFtp;
142 |         if (!ftpPassword.empty()) payload["arguments"]["ftpPassword"] = ftpPassword;
143 | 
144 |         std::cout << "📤 Sending edit user request...\n";
145 | 
146 |         // Anfrage senden und Antwort erhalten
147 |         std::string response = sendRequest(serverIp, serverPort, payload);
148 | 
149 |         std::cout << "✔️ Response from server:\n" << response << "\n";
150 |     } catch (const std::exception& e) {
151 |         std::cerr << "❌ ERROR: " << e.what() << "\n";
152 |         return 1;
153 |     }
154 | 
155 |     return 0;
156 | }
157 | 
```

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

```javascript
  1 | const net = require('net');
  2 | const readline = require('readline');
  3 | const { argv, exit } = require('process');
  4 | 
  5 | // Funktion zum Parsen der Kommandozeilenargumente
  6 | function parseArguments(args) {
  7 |     const parsedArgs = {};
  8 |     for (let i = 2; i < args.length; i++) {
  9 |         switch (args[i]) {
 10 |             case '--server-ip':
 11 |                 parsedArgs.serverIp = args[++i];
 12 |                 break;
 13 |             case '--server-port':
 14 |                 parsedArgs.serverPort = parseInt(args[++i], 10);
 15 |                 break;
 16 |             case '--token':
 17 |                 parsedArgs.token = args[++i];
 18 |                 break;
 19 |             case '--source-id':
 20 |                 parsedArgs.sourceId = args[++i];
 21 |                 break;
 22 |             case '--title':
 23 |                 parsedArgs.title = args[++i];
 24 |                 break;
 25 |             case '--content':
 26 |                 parsedArgs.content = args[++i];
 27 |                 break;
 28 |             case '--groups':
 29 |                 // Sammle alle Gruppenargumente bis zum nächsten Flag oder Ende
 30 |                 parsedArgs.groups = [];
 31 |                 while (i + 1 < args.length && !args[i + 1].startsWith('--')) {
 32 |                     parsedArgs.groups.push(args[++i]);
 33 |                 }
 34 |                 break;
 35 |             default:
 36 |                 console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
 37 |         }
 38 |     }
 39 |     return parsedArgs;
 40 | }
 41 | 
 42 | // Funktion zum interaktiven Abfragen eines Parameters (optional)
 43 | function askQuestion(query) {
 44 |     const rl = readline.createInterface({
 45 |         input: process.stdin,
 46 |         output: process.stdout,
 47 |         terminal: true
 48 |     });
 49 | 
 50 |     return new Promise((resolve) => {
 51 |         rl.question(query, (answer) => {
 52 |             rl.close();
 53 |             resolve(answer);
 54 |         });
 55 |     });
 56 | }
 57 | 
 58 | // Funktion zum Senden einer Edit-Source-Anfrage über eine TCP-Verbindung
 59 | function sendEditSourceRequest(serverIp, serverPort, payload) {
 60 |     return new Promise((resolve, reject) => {
 61 |         const client = new net.Socket();
 62 |         let responseData = '';
 63 | 
 64 |         client.connect(serverPort, serverIp, () => {
 65 |             console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
 66 |             const payloadString = JSON.stringify(payload);
 67 |             console.log(`📤 Sende Payload: ${payloadString}`);
 68 |             client.write(payloadString);
 69 |         });
 70 | 
 71 |         client.on('data', (data) => {
 72 |             console.log(`📥 Empfangene Daten: ${data}`);
 73 |             responseData += data.toString();
 74 |             try {
 75 |                 const parsedData = JSON.parse(responseData);
 76 |                 console.log('✅ JSON-Antwort erfolgreich geparst.');
 77 |                 resolve(parsedData);
 78 |                 client.destroy(); // Verbindung schließen
 79 |             } catch (err) {
 80 |                 console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.');
 81 |                 // Antwort noch nicht vollständig, weiter empfangen
 82 |             }
 83 |         });
 84 | 
 85 |         client.on('close', () => {
 86 |             console.log('🔒 Verbindung zum Server geschlossen.');
 87 |         });
 88 | 
 89 |         client.on('error', (err) => {
 90 |             console.error('❌ Verbindungsfehler:', err.message);
 91 |             reject(err);
 92 |         });
 93 |     });
 94 | }
 95 | 
 96 | // Hauptfunktion
 97 | async function main() {
 98 |     const args = argv;
 99 |     const parsedArgs = parseArguments(args);
100 |     let { serverIp, serverPort, token, sourceId, title, content, groups } = parsedArgs;
101 | 
102 |     // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen
103 |     if (!serverIp) {
104 |         serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: ');
105 |     }
106 |     if (!serverPort) {
107 |         const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: ');
108 |         serverPort = parseInt(portInput, 10);
109 |     }
110 |     if (!token) {
111 |         token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: ');
112 |     }
113 |     if (!sourceId) {
114 |         sourceId = await askQuestion('📁 Bitte gib die Source-ID ein: ');
115 |     }
116 | 
117 |     // Überprüfen, ob mindestens eines der optionalen Parameter vorhanden ist
118 |     if (title === undefined && content === undefined && (groups === undefined || groups.length === 0)) {
119 |         console.warn('⚠️ Keine Änderungsparameter angegeben. Es werden mindestens eines der folgenden benötigt: --title, --content, --groups.');
120 |         exit(1);
121 |     }
122 | 
123 |     // Optional: Abfrage fehlender optionaler Parameter, wenn entsprechende Flags gesetzt sind
124 |     // Hier gehen wir davon aus, dass --title, --content und --groups bereits korrekt geparst wurden
125 |     // und entweder definiert sind oder nicht angegeben wurden.
126 | 
127 |     // Entferne unerwünschte Schlüssel mit undefined oder null Werten
128 |     const filteredArguments = {};
129 |     if (sourceId) filteredArguments.sourceId = sourceId;
130 |     if (title) filteredArguments.title = title;
131 |     if (content) filteredArguments.content = content;
132 |     if (groups && groups.length > 0) filteredArguments.groups = groups;
133 | 
134 |     const payload = {
135 |         command: "edit_source",
136 |         token: token,
137 |         arguments: filteredArguments
138 |     };
139 | 
140 |     try {
141 |         console.log('🛠️ Sende Edit-Source-Anfrage...');
142 |         const response = await sendEditSourceRequest(serverIp, serverPort, payload);
143 |         console.log('✅ Server Response:');
144 |         console.log(JSON.stringify(response, null, 2));
145 |     } catch (err) {
146 |         console.error('❌ ERROR:', err.message);
147 |     }
148 | }
149 | 
150 | main();
151 | 
```

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

```javascript
  1 | const net = require('net');
  2 | const readline = require('readline');
  3 | const { argv, exit } = require('process');
  4 | 
  5 | /**
  6 |  * Funktion zum Parsen der Kommandozeilenargumente
  7 |  * @param {string[]} args - Array von Kommandozeilenargumenten
  8 |  * @returns {Object} - Objekt mit geparsten Argumenten
  9 |  */
 10 | function parseArguments(args) {
 11 |     const parsedArgs = {};
 12 |     for (let i = 2; i < args.length; i++) {
 13 |         switch (args[i]) {
 14 |             case '--server-ip':
 15 |                 parsedArgs.serverIp = args[++i];
 16 |                 break;
 17 |             case '--server-port':
 18 |                 parsedArgs.serverPort = parseInt(args[++i], 10);
 19 |                 break;
 20 |             case '--group-name':
 21 |                 parsedArgs.groupName = args[++i];
 22 |                 break;
 23 |             case '--token':
 24 |                 parsedArgs.token = args[++i];
 25 |                 break;
 26 |             case '--description':
 27 |                 parsedArgs.description = args[++i];
 28 |                 break;
 29 |             default:
 30 |                 console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
 31 |         }
 32 |     }
 33 |     return parsedArgs;
 34 | }
 35 | 
 36 | /**
 37 |  * Funktion zum interaktiven Abfragen eines Parameters (optional)
 38 |  * @param {string} query - Frage an den Benutzer
 39 |  * @returns {Promise<string>} - Antwort des Benutzers
 40 |  */
 41 | function askQuestion(query) {
 42 |     const rl = readline.createInterface({
 43 |         input: process.stdin,
 44 |         output: process.stdout,
 45 |         terminal: true
 46 |     });
 47 | 
 48 |     return new Promise((resolve) => {
 49 |         rl.question(query, (answer) => {
 50 |             rl.close();
 51 |             resolve(answer);
 52 |         });
 53 |     });
 54 | }
 55 | 
 56 | /**
 57 |  * Sendet eine Anfrage an den MCP-Server, um eine neue Gruppe zu speichern.
 58 |  *
 59 |  * @param {string} serverIp - IP-Adresse des MCP-Servers
 60 |  * @param {number} serverPort - Portnummer des MCP-Servers
 61 |  * @param {string} groupName - Name der zu speichernden Gruppe
 62 |  * @param {string} token - Authentifizierungstoken
 63 |  * @param {string} description - Beschreibung der Gruppe (optional)
 64 |  * @returns {Promise<Object>} - Antwort vom Server
 65 |  */
 66 | function sendStoreGroupRequest(serverIp, serverPort, groupName, token, description) {
 67 |     return new Promise((resolve, reject) => {
 68 |         const client = new net.Socket();
 69 |         const payload = {
 70 |             command: "store_group",
 71 |             token: token,
 72 |             arguments: {
 73 |                 groupName: groupName,
 74 |                 description: description
 75 |             }
 76 |         };
 77 |         const payloadString = JSON.stringify(payload);
 78 | 
 79 |         // Timeout setzen (optional)
 80 |         const TIMEOUT_DURATION = 10000; // 10 Sekunden
 81 |         const timeout = setTimeout(() => {
 82 |             client.destroy(); // Verbindung zerstören
 83 |             reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.'));
 84 |         }, TIMEOUT_DURATION);
 85 | 
 86 |         client.connect(serverPort, serverIp, () => {
 87 |             console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
 88 |             console.log(`📤 Sende Payload: ${payloadString}`);
 89 |             client.write(payloadString);
 90 |         });
 91 | 
 92 |         let responseData = '';
 93 | 
 94 |         client.on('data', (data) => {
 95 |             console.log(`📥 Empfangene Daten: ${data}`);
 96 |             responseData += data.toString();
 97 |             try {
 98 |                 const parsedData = JSON.parse(responseData);
 99 |                 console.log('✅ JSON-Antwort erfolgreich geparst.');
100 |                 clearTimeout(timeout);
101 |                 resolve(parsedData);
102 |                 client.destroy(); // Verbindung schließen
103 |             } catch (err) {
104 |                 console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.');
105 |                 // Weiter empfangen
106 |             }
107 |         });
108 | 
109 |         client.on('close', () => {
110 |             console.log('🔒 Verbindung zum Server geschlossen.');
111 |             clearTimeout(timeout);
112 |         });
113 | 
114 |         client.on('error', (err) => {
115 |             console.error('❌ Verbindungsfehler:', err.message);
116 |             clearTimeout(timeout);
117 |             reject(err);
118 |         });
119 |     });
120 | }
121 | 
122 | // Hauptfunktion
123 | async function main() {
124 |     const args = argv;
125 |     const parsedArgs = parseArguments(args);
126 |     let { serverIp, serverPort, groupName, token, description } = parsedArgs;
127 | 
128 |     // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen
129 |     if (!serverIp) {
130 |         serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: ');
131 |     }
132 |     if (!serverPort) {
133 |         const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: ');
134 |         serverPort = parseInt(portInput, 10);
135 |     }
136 |     if (!groupName) {
137 |         groupName = await askQuestion('📛 Bitte gib den Gruppennamen ein: ');
138 |     }
139 |     if (!token) {
140 |         token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: ');
141 |     }
142 |     // Beschreibung ist optional, kein Abfrage notwendig
143 | 
144 |     const payload = {
145 |         command: "store_group",
146 |         token: token,
147 |         arguments: {
148 |             groupName: groupName,
149 |             description: description || ""
150 |         }
151 |     };
152 | 
153 |     try {
154 |         console.log('🗃️ Sende Store-Group-Anfrage...');
155 |         const response = await sendStoreGroupRequest(serverIp, serverPort, groupName, token, description);
156 |         console.log('✔️ Antwort vom Server:', JSON.stringify(response, null, 2));
157 |     } catch (err) {
158 |         console.error('❌ Fehler:', err.message);
159 |     }
160 | }
161 | 
162 | main();
163 | 
```

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

```javascript
  1 | const net = require('net');
  2 | const readline = require('readline');
  3 | const { argv } = require('process');
  4 | 
  5 | /**
  6 |  * Funktion zum Parsen der Kommandozeilenargumente
  7 |  * @param {string[]} args - Array von Kommandozeilenargumenten
  8 |  * @returns {Object} - Objekt mit geparsten Argumenten
  9 |  */
 10 | function parseArguments(args) {
 11 |     const parsedArgs = {};
 12 |     for (let i = 2; i < args.length; i++) {
 13 |         switch (args[i]) {
 14 |             case '--server-ip':
 15 |                 parsedArgs.serverIp = args[++i];
 16 |                 break;
 17 |             case '--server-port':
 18 |                 parsedArgs.serverPort = parseInt(args[++i], 10);
 19 |                 break;
 20 |             case '--token':
 21 |                 parsedArgs.token = args[++i];
 22 |                 break;
 23 |             case '--name':
 24 |                 parsedArgs.name = args[++i];
 25 |                 break;
 26 |             case '--email':
 27 |                 parsedArgs.email = args[++i];
 28 |                 break;
 29 |             case '--password':
 30 |                 parsedArgs.password = args[++i];
 31 |                 break;
 32 |             case '--language':
 33 |                 parsedArgs.language = args[++i];
 34 |                 break;
 35 |             case '--timezone':
 36 |                 parsedArgs.timezone = args[++i];
 37 |                 break;
 38 |             case '--roles':
 39 |                 parsedArgs.roles = [];
 40 |                 while (i + 1 < args.length && !args[i + 1].startsWith('--')) {
 41 |                     parsedArgs.roles.push(args[++i]);
 42 |                 }
 43 |                 break;
 44 |             case '--groups':
 45 |                 parsedArgs.groups = [];
 46 |                 while (i + 1 < args.length && !args[i + 1].startsWith('--')) {
 47 |                     parsedArgs.groups.push(args[++i]);
 48 |                 }
 49 |                 break;
 50 |             case '--usePublic':
 51 |                 parsedArgs.usePublic = true;
 52 |                 break;
 53 |             case '--activateFtp':
 54 |                 parsedArgs.activateFtp = true;
 55 |                 break;
 56 |             case '--ftpPassword':
 57 |                 parsedArgs.ftpPassword = args[++i];
 58 |                 break;
 59 |             default:
 60 |                 console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
 61 |         }
 62 |     }
 63 |     return parsedArgs;
 64 | }
 65 | 
 66 | /**
 67 |  * Sendet eine Anfrage an den MCP-Server, um einen Benutzer zu bearbeiten.
 68 |  *
 69 |  * @param {string} serverIp - IP-Adresse des MCP-Servers
 70 |  * @param {number} serverPort - Portnummer des MCP-Servers
 71 |  * @param {string} token - Authentifizierungstoken
 72 |  * @param {Object} args - Argumente für den zu bearbeitenden Benutzer
 73 |  * @returns {Promise<string>} - Antwort vom Server
 74 |  */
 75 | function sendEditUserRequest(serverIp, serverPort, token, args) {
 76 |     return new Promise((resolve, reject) => {
 77 |         const client = new net.Socket();
 78 |         const payload = {
 79 |             command: "edit_user",
 80 |             token: token,
 81 |             arguments: {
 82 |                 name: args.name,
 83 |                 email: args.email,
 84 |                 password: args.password,
 85 |                 language: args.language,
 86 |                 timezone: args.timezone,
 87 |                 roles: args.roles || [],
 88 |                 groups: args.groups || [],
 89 |                 usePublic: args.usePublic || false,
 90 |                 activateFtp: args.activateFtp || false,
 91 |                 ftpPassword: args.ftpPassword
 92 |             }
 93 |         };
 94 | 
 95 |         // Entferne Null- oder undefined-Werte
 96 |         payload.arguments = Object.fromEntries(Object.entries(payload.arguments).filter(([_, v]) => v != null));
 97 | 
 98 |         const payloadString = JSON.stringify(payload);
 99 | 
100 |         // Timeout setzen
101 |         const TIMEOUT_DURATION = 10000; // 10 Sekunden
102 |         const timeout = setTimeout(() => {
103 |             client.destroy();
104 |             reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.'));
105 |         }, TIMEOUT_DURATION);
106 | 
107 |         client.connect(serverPort, serverIp, () => {
108 |             console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
109 |             console.log(`📤 Sende Payload: ${payloadString}`);
110 |             client.write(payloadString);
111 |         });
112 | 
113 |         let responseData = '';
114 | 
115 |         client.on('data', (data) => {
116 |             responseData += data.toString();
117 |             try {
118 |                 const parsedData = JSON.parse(responseData);
119 |                 clearTimeout(timeout);
120 |                 resolve(parsedData);
121 |                 client.destroy();
122 |             } catch (e) {
123 |                 // Weiter empfangen, falls JSON unvollständig ist
124 |             }
125 |         });
126 | 
127 |         client.on('close', () => {
128 |             console.log('🔒 Verbindung zum Server geschlossen.');
129 |         });
130 | 
131 |         client.on('error', (err) => {
132 |             clearTimeout(timeout);
133 |             reject(err);
134 |         });
135 |     });
136 | }
137 | 
138 | // Hauptfunktion
139 | async function main() {
140 |     const args = parseArguments(argv);
141 | 
142 |     if (!args.serverIp || !args.serverPort || !args.token) {
143 |         console.error('❌ Fehler: --server-ip, --server-port und --token sind erforderlich.');
144 |         console.log('📖 Beispiel: node MCPEditUserClient.js --server-ip 192.168.0.1 --server-port 5000 --token YOUR_AUTH_TOKEN');
145 |         process.exit(1);
146 |     }
147 | 
148 |     try {
149 |         console.log('🧑‍💻 Sende Edit-User-Anfrage...');
150 |         const response = await sendEditUserRequest(
151 |             args.serverIp,
152 |             args.serverPort,
153 |             args.token,
154 |             args
155 |         );
156 |         console.log('✔️ Antwort vom Server:', JSON.stringify(response, null, 2));
157 |     } catch (err) {
158 |         console.error('❌ Fehler beim Bearbeiten des Benutzers:', err.message);
159 |     }
160 | }
161 | 
162 | main();
163 | 
```

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

```java
  1 | import org.json.JSONArray;
  2 | import org.json.JSONObject;
  3 | 
  4 | import java.io.IOException;
  5 | import java.io.InputStream;
  6 | import java.io.OutputStream;
  7 | import java.net.Socket;
  8 | import java.nio.charset.StandardCharsets;
  9 | import java.util.ArrayList;
 10 | import java.util.Arrays;
 11 | import java.util.List;
 12 | 
 13 | public class MCPChatClient {
 14 | 
 15 |     public static void main(String[] args) {
 16 |         // Minimalprüfung, ob genug Argumente für --server-ip, --server-port, --token, --question vorliegen.
 17 |         // (Die eigentliche Prüfung machen wir etwas weiter unten ausführlicher.)
 18 |         if (args.length < 5) {
 19 |             printUsage();
 20 |             return;
 21 |         }
 22 | 
 23 |         // Argumente auslesen
 24 |         String serverIp = getArgument(args, "--server-ip");
 25 |         String serverPortStr = getArgument(args, "--server-port");
 26 |         String token = getArgument(args, "--token");
 27 |         String question = getArgument(args, "--question");
 28 |         boolean usePublic = Arrays.asList(args).contains("--use-public");
 29 |         String language = getArgument(args, "--language");
 30 |         if (language == null) {
 31 |             language = "de"; // Defaultwert wie im Original
 32 |         }
 33 | 
 34 |         // Groups (kommagetrennt)
 35 |         List<String> groups = new ArrayList<>();
 36 |         String groupsArgument = getArgument(args, "--groups");
 37 |         if (groupsArgument != null) {
 38 |             // Zerlege den String an Kommas
 39 |             String[] groupArray = groupsArgument.split(",");
 40 |             groups.addAll(Arrays.asList(groupArray));
 41 |         }
 42 | 
 43 |         // Vollständige Prüfung
 44 |         if (serverIp == null || serverPortStr == null || token == null || question == null) {
 45 |             printUsage();
 46 |             return;
 47 |         }
 48 | 
 49 |         int serverPort = Integer.parseInt(serverPortStr);
 50 | 
 51 |         // Anfrage an den Server stellen
 52 |         String response = sendMCPRequest(serverIp, serverPort, token, question, usePublic, groups, language);
 53 |         System.out.println("Response from server:");
 54 |         System.out.println(response);
 55 |     }
 56 | 
 57 |     /**
 58 |      * Liest den Wert eines Arguments aus (z.B. --server-ip 127.0.0.1).
 59 |      * Gibt null zurück, wenn der Schlüssel nicht gefunden wurde.
 60 |      */
 61 |     private static String getArgument(String[] args, String key) {
 62 |         for (int i = 0; i < args.length - 1; i++) {
 63 |             if (args[i].equals(key)) {
 64 |                 // Gib das nächste Element zurück, sofern vorhanden
 65 |                 return args[i + 1];
 66 |             }
 67 |         }
 68 |         return null;
 69 |     }
 70 | 
 71 |     /**
 72 |      * Stellt eine Socket-Verbindung her, sendet das JSON-Payload und empfängt die Antwort.
 73 |      */
 74 |     private static String sendMCPRequest(String serverIp,
 75 |                                          int serverPort,
 76 |                                          String token,
 77 |                                          String question,
 78 |                                          boolean usePublic,
 79 |                                          List<String> groups,
 80 |                                          String language) {
 81 | 
 82 |         // Payload aufbauen
 83 |         JSONObject payload = new JSONObject();
 84 |         payload.put("command", "chat");
 85 |         payload.put("token", token);
 86 | 
 87 |         // arguments
 88 |         JSONObject arguments = new JSONObject();
 89 |         arguments.put("question", question);
 90 |         arguments.put("usePublic", usePublic);
 91 |         arguments.put("language", language);
 92 | 
 93 |         // Falls du lieber ein reines Array statt List speichern möchtest,
 94 |         // kannst du direkt new JSONArray(groups) verwenden.
 95 |         // Hier konvertieren wir die Java-Liste in ein JSONArray:
 96 |         JSONArray groupsArray = new JSONArray(groups);
 97 |         arguments.put("groups", groupsArray);
 98 | 
 99 |         payload.put("arguments", arguments);
100 | 
101 |         // Konvertiere das JSON-Objekt in einen String
102 |         String payloadJson = payload.toString();
103 | 
104 |         try (Socket client = new Socket(serverIp, serverPort)) {
105 |             // Sende das JSON-Payload
106 |             OutputStream outputStream = client.getOutputStream();
107 |             byte[] data = payloadJson.getBytes(StandardCharsets.UTF_8);
108 |             outputStream.write(data);
109 |             outputStream.flush();
110 | 
111 |             // Antwort empfangen
112 |             InputStream inputStream = client.getInputStream();
113 |             byte[] buffer = new byte[4096];
114 |             StringBuilder responseBuilder = new StringBuilder();
115 | 
116 |             int bytesRead;
117 |             do {
118 |                 bytesRead = inputStream.read(buffer);
119 |                 if (bytesRead > 0) {
120 |                     responseBuilder.append(new String(buffer, 0, bytesRead, StandardCharsets.UTF_8));
121 |                 }
122 |             } while (bytesRead == buffer.length);
123 | 
124 |             return responseBuilder.toString();
125 | 
126 |         } catch (IOException e) {
127 |             // Fehler in ein JSON-Objekt packen, wie im Original
128 |             JSONObject errorResponse = new JSONObject();
129 |             errorResponse.put("status", "error");
130 |             errorResponse.put("message", e.getMessage());
131 |             return errorResponse.toString();
132 |         }
133 |     }
134 | 
135 |     private static void printUsage() {
136 |         System.out.println("Usage: ");
137 |         System.out.println("  --server-ip <IP> --server-port <PORT> --token <TOKEN> --question <QUESTION>");
138 |         System.out.println("  [--use-public] [--groups <GROUPS>] [--language <LANGUAGE>]");
139 |         System.out.println();
140 |         System.out.println("Example:");
141 |         System.out.println("  java -cp .;json-20241224.jar MCPChatClient --server-ip 127.0.0.1 --server-port 1234 \\");
142 |         System.out.println("       --token 12345 --question \"Hallo Welt?\" --use-public --groups \"devops,hr\"");
143 |     }
144 | }
145 | 
```

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

```python
  1 | # transport/stdio/stdio_client.py
  2 | import json
  3 | import logging
  4 | import sys
  5 | import traceback
  6 | from contextlib import asynccontextmanager
  7 | 
  8 | import anyio
  9 | from anyio.streams.text import TextReceiveStream
 10 | 
 11 | from ...mcp_client import get_default_environment
 12 | from ...messages.message_types.json_rpc_message import JSONRPCMessage
 13 | from ...transport.stdio.stdio_server_parameters import StdioServerParameters
 14 | 
 15 | 
 16 | @asynccontextmanager
 17 | async def stdio_client(server: StdioServerParameters):
 18 |     # ensure we have a server command
 19 |     if not server.command:
 20 |         raise ValueError("Server command must not be empty.")
 21 | 
 22 |     # ensure we have server arguments as a list or tuple
 23 |     if not isinstance(server.args, (list, tuple)):
 24 |         raise ValueError("Server arguments must be a list or tuple.")
 25 | 
 26 |     # create the the read and write streams
 27 |     read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
 28 |     write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
 29 | 
 30 |     # start the subprocess
 31 |     process = await anyio.open_process(
 32 |         [server.command, *server.args],
 33 |         env={**get_default_environment(), **(server.env or {})},
 34 |         stderr=sys.stderr,
 35 |     )
 36 | 
 37 |     # started server
 38 |     logging.debug(
 39 |         f"Subprocess started with PID {process.pid}, command: {server.command}"
 40 |     )
 41 | 
 42 |     # create a task to read from the subprocess' stdout
 43 |     async def process_json_line(line: str, writer):
 44 |         try:
 45 |             logging.debug(f"Processing line: {line.strip()}")
 46 |             data = json.loads(line)
 47 | 
 48 |             # parse the json
 49 |             logging.debug(f"Parsed JSON data: {data}")
 50 | 
 51 |             # validate the jsonrpc message
 52 |             message = JSONRPCMessage.model_validate(data)
 53 |             logging.debug(f"Validated JSONRPCMessage: {message}")
 54 | 
 55 |             # send the message
 56 |             await writer.send(message)
 57 |         except json.JSONDecodeError as exc:
 58 |             # not valid json
 59 |             logging.error(f"JSON decode error: {exc}. Line: {line.strip()}")
 60 |         except Exception as exc:
 61 |             # other exception
 62 |             logging.error(f"Error processing message: {exc}. Line: {line.strip()}")
 63 |             logging.debug(f"Traceback:\n{traceback.format_exc()}")
 64 | 
 65 |     async def stdout_reader():
 66 |         """Read JSON-RPC messages from the server's stdout."""
 67 |         assert process.stdout, "Opened process is missing stdout"
 68 |         buffer = ""
 69 |         logging.debug("Starting stdout_reader")
 70 |         try:
 71 |             async with read_stream_writer:
 72 |                 async for chunk in TextReceiveStream(process.stdout):
 73 |                     lines = (buffer + chunk).split("\n")
 74 |                     buffer = lines.pop()
 75 |                     for line in lines:
 76 |                         if line.strip():
 77 |                             await process_json_line(line, read_stream_writer)
 78 |                 if buffer.strip():
 79 |                     await process_json_line(buffer, read_stream_writer)
 80 |         except anyio.ClosedResourceError:
 81 |             logging.debug("Read stream closed.")
 82 |         except Exception as exc:
 83 |             logging.error(f"Unexpected error in stdout_reader: {exc}")
 84 |             logging.debug(f"Traceback:\n{traceback.format_exc()}")
 85 |             raise
 86 |         finally:
 87 |             logging.debug("Exiting stdout_reader")
 88 | 
 89 |     async def stdin_writer():
 90 |         """Send JSON-RPC messages from the write stream to the server's stdin."""
 91 |         assert process.stdin, "Opened process is missing stdin"
 92 |         logging.debug("Starting stdin_writer")
 93 |         try:
 94 |             async with write_stream_reader:
 95 |                 async for message in write_stream_reader:
 96 |                     json_str = message.model_dump_json(exclude_none=True)
 97 |                     logging.debug(f"Sending: {json_str}")
 98 |                     await process.stdin.send((json_str + "\n").encode())
 99 |         except anyio.ClosedResourceError:
100 |             logging.debug("Write stream closed.")
101 |         except Exception as exc:
102 |             logging.error(f"Unexpected error in stdin_writer: {exc}")
103 |             logging.debug(f"Traceback:\n{traceback.format_exc()}")
104 |             raise
105 |         finally:
106 |             logging.debug("Exiting stdin_writer")
107 | 
108 |     async def terminate_process():
109 |         """Gracefully terminate the subprocess."""
110 |         try:
111 |             if process.returncode is None:  # Process is still running
112 |                 logging.debug("Terminating subprocess...")
113 |                 process.terminate()
114 |                 with anyio.fail_after(5):
115 |                     await process.wait()
116 |             else:
117 |                 logging.info("Process already terminated.")
118 |         except TimeoutError:
119 |             logging.warning(
120 |                 "Process did not terminate gracefully. Forcefully killing it."
121 |             )
122 |             try:
123 |                 process.kill()
124 |             except Exception as kill_exc:
125 |                 logging.error(f"Error killing process: {kill_exc}")
126 |         except Exception as exc:
127 |             logging.error(f"Error during process termination: {exc}")
128 | 
129 |     try:
130 |         async with anyio.create_task_group() as tg, process:
131 |             tg.start_soon(stdout_reader)
132 |             tg.start_soon(stdin_writer)
133 |             yield read_stream, write_stream
134 | 
135 |         # exit the task group
136 |         exit_code = await process.wait()
137 |         logging.info(f"Process exited with code {exit_code}")
138 |     except Exception as exc:
139 |         # other exception
140 |         logging.error(f"Unhandled error in TaskGroup: {exc}")
141 |         logging.debug(f"Traceback:\n{traceback.format_exc()}")
142 |         if hasattr(exc, "__cause__") and exc.__cause__:
143 |             logging.debug(f"TaskGroup exception cause: {exc.__cause__}")
144 |         raise
145 |     finally:
146 |         await terminate_process()
147 | 
```

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

```python
  1 | # transport/stdio/stdio_client.py
  2 | import json
  3 | import logging
  4 | import sys
  5 | import traceback
  6 | from contextlib import asynccontextmanager
  7 | 
  8 | import anyio
  9 | from anyio.streams.text import TextReceiveStream
 10 | 
 11 | from ...environment import get_default_environment
 12 | from ...messages.message_types.json_rpc_message import JSONRPCMessage
 13 | from ...transport.stdio.stdio_server_parameters import StdioServerParameters
 14 | 
 15 | 
 16 | @asynccontextmanager
 17 | async def stdio_client(server: StdioServerParameters):
 18 |     # ensure we have a server command
 19 |     if not server.command:
 20 |         raise ValueError("Server command must not be empty.")
 21 | 
 22 |     # ensure we have server arguments as a list or tuple
 23 |     if not isinstance(server.args, (list, tuple)):
 24 |         raise ValueError("Server arguments must be a list or tuple.")
 25 | 
 26 |     # create the the read and write streams
 27 |     read_stream_writer, read_stream = anyio.create_memory_object_stream(0)
 28 |     write_stream, write_stream_reader = anyio.create_memory_object_stream(0)
 29 | 
 30 |     # start the subprocess
 31 |     process = await anyio.open_process(
 32 |         [server.command, *server.args],
 33 |         env={**get_default_environment(), **(server.env or {})},
 34 |         stderr=sys.stderr,
 35 |     )
 36 | 
 37 |     # started server
 38 |     logging.debug(
 39 |         f"Subprocess started with PID {process.pid}, command: {server.command}"
 40 |     )
 41 | 
 42 |     # create a task to read from the subprocess' stdout
 43 |     async def process_json_line(line: str, writer):
 44 |         try:
 45 |             logging.debug(f"Processing line: {line.strip()}")
 46 |             data = json.loads(line)
 47 | 
 48 |             # parse the json
 49 |             logging.debug(f"Parsed JSON data: {data}")
 50 | 
 51 |             # validate the jsonrpc message
 52 |             message = JSONRPCMessage.model_validate(data)
 53 |             logging.debug(f"Validated JSONRPCMessage: {message}")
 54 | 
 55 |             # send the message
 56 |             await writer.send(message)
 57 |         except json.JSONDecodeError as exc:
 58 |             # not valid json
 59 |             logging.error(f"JSON decode error: {exc}. Line: {line.strip()}")
 60 |         except Exception as exc:
 61 |             # other exception
 62 |             logging.error(f"Error processing message: {exc}. Line: {line.strip()}")
 63 |             logging.debug(f"Traceback:\n{traceback.format_exc()}")
 64 | 
 65 |     async def stdout_reader():
 66 |         """Read JSON-RPC messages from the server's stdout."""
 67 |         assert process.stdout, "Opened process is missing stdout"
 68 |         buffer = ""
 69 |         logging.debug("Starting stdout_reader")
 70 |         try:
 71 |             async with read_stream_writer:
 72 |                 async for chunk in TextReceiveStream(process.stdout):
 73 |                     lines = (buffer + chunk).split("\n")
 74 |                     buffer = lines.pop()
 75 |                     for line in lines:
 76 |                         if line.strip():
 77 |                             await process_json_line(line, read_stream_writer)
 78 |                 if buffer.strip():
 79 |                     await process_json_line(buffer, read_stream_writer)
 80 |         except anyio.ClosedResourceError:
 81 |             logging.debug("Read stream closed.")
 82 |         except Exception as exc:
 83 |             logging.error(f"Unexpected error in stdout_reader: {exc}")
 84 |             logging.debug(f"Traceback:\n{traceback.format_exc()}")
 85 |             raise
 86 |         finally:
 87 |             logging.debug("Exiting stdout_reader")
 88 | 
 89 |     async def stdin_writer():
 90 |         """Send JSON-RPC messages from the write stream to the server's stdin."""
 91 |         assert process.stdin, "Opened process is missing stdin"
 92 |         logging.debug("Starting stdin_writer")
 93 |         try:
 94 |             async with write_stream_reader:
 95 |                 async for message in write_stream_reader:
 96 |                     json_str = message.model_dump_json(exclude_none=True)
 97 |                     logging.debug(f"Sending: {json_str}")
 98 |                     await process.stdin.send((json_str + "\n").encode())
 99 |         except anyio.ClosedResourceError:
100 |             logging.debug("Write stream closed.")
101 |         except Exception as exc:
102 |             logging.error(f"Unexpected error in stdin_writer: {exc}")
103 |             logging.debug(f"Traceback:\n{traceback.format_exc()}")
104 |             raise
105 |         finally:
106 |             logging.debug("Exiting stdin_writer")
107 | 
108 |     async def terminate_process():
109 |         """Gracefully terminate the subprocess."""
110 |         try:
111 |             if process.returncode is None:  # Process is still running
112 |                 logging.debug("Terminating subprocess...")
113 |                 process.terminate()
114 |                 with anyio.fail_after(5):
115 |                     await process.wait()
116 |             else:
117 |                 logging.info("Process already terminated.")
118 |         except TimeoutError:
119 |             logging.warning(
120 |                 "Process did not terminate gracefully. Forcefully killing it."
121 |             )
122 |             try:
123 |                 process.kill()
124 |             except Exception as kill_exc:
125 |                 logging.error(f"Error killing process: {kill_exc}")
126 |         except Exception as exc:
127 |             logging.error(f"Error during process termination: {exc}")
128 | 
129 |     try:
130 |         async with anyio.create_task_group() as tg, process:
131 |             tg.start_soon(stdout_reader)
132 |             tg.start_soon(stdin_writer)
133 |             yield read_stream, write_stream
134 | 
135 |         # exit the task group
136 |         exit_code = await process.wait()
137 |         logging.info(f"Process exited with code {exit_code}")
138 |     except Exception as exc:
139 |         # other exception
140 |         logging.error(f"Unhandled error in TaskGroup: {exc}")
141 |         logging.debug(f"Traceback:\n{traceback.format_exc()}")
142 |         if hasattr(exc, "__cause__") and exc.__cause__:
143 |             logging.debug(f"TaskGroup exception cause: {exc.__cause__}")
144 |         raise
145 |     finally:
146 |         await terminate_process()
147 | 
```

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

```javascript
  1 | const net = require('net');
  2 | const readline = require('readline');
  3 | const { argv, exit } = require('process');
  4 | 
  5 | /**
  6 |  * Funktion zum Parsen der Kommandozeilenargumente
  7 |  * @param {string[]} args - Array von Kommandozeilenargumenten
  8 |  * @returns {Object} - Objekt mit geparsten Argumenten
  9 |  */
 10 | function parseArguments(args) {
 11 |     const parsedArgs = {};
 12 |     for (let i = 2; i < args.length; i++) {
 13 |         switch (args[i]) {
 14 |             case '--server-ip':
 15 |                 if (i + 1 < args.length) {
 16 |                     parsedArgs.serverIp = args[++i];
 17 |                 } else {
 18 |                     console.warn('⚠️ Kein Wert für --server-ip angegeben.');
 19 |                 }
 20 |                 break;
 21 |             case '--server-port':
 22 |                 if (i + 1 < args.length) {
 23 |                     parsedArgs.serverPort = parseInt(args[++i], 10);
 24 |                 } else {
 25 |                     console.warn('⚠️ Kein Wert für --server-port angegeben.');
 26 |                 }
 27 |                 break;
 28 |             case '--token':
 29 |                 if (i + 1 < args.length) {
 30 |                     parsedArgs.token = args[++i];
 31 |                 } else {
 32 |                     console.warn('⚠️ Kein Wert für --token angegeben.');
 33 |                 }
 34 |                 break;
 35 |             case '--group-name':
 36 |                 if (i + 1 < args.length) {
 37 |                     parsedArgs.groupName = args[++i];
 38 |                 } else {
 39 |                     console.warn('⚠️ Kein Wert für --group-name angegeben.');
 40 |                 }
 41 |                 break;
 42 |             default:
 43 |                 console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`);
 44 |         }
 45 |     }
 46 |     return parsedArgs;
 47 | }
 48 | 
 49 | /**
 50 |  * Funktion zum interaktiven Abfragen eines Parameters (optional)
 51 |  * @param {string} query - Frage an den Benutzer
 52 |  * @returns {Promise<string>} - Antwort des Benutzers
 53 |  */
 54 | function askQuestion(query) {
 55 |     const rl = readline.createInterface({
 56 |         input: process.stdin,
 57 |         output: process.stdout,
 58 |         terminal: true
 59 |     });
 60 | 
 61 |     return new Promise((resolve) => {
 62 |         rl.question(query, (answer) => {
 63 |             rl.close();
 64 |             resolve(answer);
 65 |         });
 66 |     });
 67 | }
 68 | 
 69 | /**
 70 |  * Sendet eine Anfrage an den MCP-Server, um eine bestehende Gruppe zu löschen.
 71 |  *
 72 |  * @param {string} serverIp - IP-Adresse des MCP-Servers
 73 |  * @param {number} serverPort - Portnummer des MCP-Servers
 74 |  * @param {string} token - Authentifizierungstoken
 75 |  * @param {string} groupName - Name der zu löschenden Gruppe
 76 |  * @returns {Promise<Object>} - Antwort vom Server
 77 |  */
 78 | function sendDeleteGroupRequest(serverIp, serverPort, token, groupName) {
 79 |     return new Promise((resolve, reject) => {
 80 |         const client = new net.Socket();
 81 |         const payload = {
 82 |             command: "delete_group",
 83 |             token: token,
 84 |             arguments: {
 85 |                 groupName: groupName
 86 |             }
 87 |         };
 88 |         const payloadString = JSON.stringify(payload);
 89 | 
 90 |         // Timeout setzen (optional)
 91 |         const TIMEOUT_DURATION = 10000; // 10 Sekunden
 92 |         const timeout = setTimeout(() => {
 93 |             client.destroy(); // Verbindung zerstören
 94 |             reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.'));
 95 |         }, TIMEOUT_DURATION);
 96 | 
 97 |         client.connect(serverPort, serverIp, () => {
 98 |             console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`);
 99 |             console.log(`📤 Sende Payload: ${payloadString}`);
100 |             client.write(payloadString);
101 |         });
102 | 
103 |         let responseData = '';
104 | 
105 |         client.on('data', (data) => {
106 |             console.log(`📥 Empfangene Daten: ${data}`);
107 |             responseData += data.toString();
108 |             try {
109 |                 const parsedData = JSON.parse(responseData);
110 |                 console.log('✅ JSON-Antwort erfolgreich geparst.');
111 |                 clearTimeout(timeout);
112 |                 resolve(parsedData);
113 |                 client.destroy(); // Verbindung schließen
114 |             } catch (err) {
115 |                 console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.');
116 |                 // Weiter empfangen
117 |             }
118 |         });
119 | 
120 |         client.on('close', () => {
121 |             console.log('🔒 Verbindung zum Server geschlossen.');
122 |             clearTimeout(timeout);
123 |         });
124 | 
125 |         client.on('error', (err) => {
126 |             console.error('❌ Verbindungsfehler:', err.message);
127 |             clearTimeout(timeout);
128 |             reject(err);
129 |         });
130 |     });
131 | }
132 | 
133 | // Hauptfunktion
134 | async function main() {
135 |     const args = argv;
136 |     const parsedArgs = parseArguments(args);
137 |     let { serverIp, serverPort, token, groupName } = parsedArgs;
138 | 
139 |     // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen
140 |     if (!serverIp) {
141 |         serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: ');
142 |     }
143 |     if (!serverPort) {
144 |         const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: ');
145 |         serverPort = parseInt(portInput, 10);
146 |     }
147 |     if (!token) {
148 |         token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: ');
149 |     }
150 |     if (!groupName) {
151 |         groupName = await askQuestion('👥 Bitte gib den Namen der Gruppe ein: ');
152 |     }
153 | 
154 |     const payload = {
155 |         command: "delete_group",
156 |         token: token,
157 |         arguments: {
158 |             groupName: groupName
159 |         }
160 |     };
161 | 
162 |     try {
163 |         console.log('🗑️ Sende Delete-Group-Anfrage...');
164 |         const response = await sendDeleteGroupRequest(serverIp, serverPort, token, groupName);
165 |         console.log('✔️ Antwort vom Server:', JSON.stringify(response, null, 2));
166 |     } catch (err) {
167 |         console.error('❌ Fehler:', err.message);
168 |     }
169 | }
170 | 
171 | main();
172 | 
```

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

```python
  1 | import json
  2 | from pathlib import Path
  3 | 
  4 | from starlette.responses import StreamingResponse
  5 | 
  6 | from fastapi import FastAPI, Request, HTTPException
  7 | from threading import local
  8 | 
  9 | from agents.OpenAI_Compatible_API_Agent.Python.open_ai_helper import ChatInstance, \
 10 |     ChatCompletionRequest, CompletionRequest, _resp_sync, _resp_async_generator, models, Message, _resp_async_generator_completions, _resp_sync_completions
 11 | from .privategpt_api import PrivateGPTAPI
 12 | 
 13 | from ...AgentInterface.Python.config import Config, ConfigError
 14 | import uvicorn
 15 | 
 16 | app = FastAPI(title="OpenAI-compatible API for PrivateGPT")
 17 | request_context = local()
 18 | instances = []
 19 | 
 20 | # Konfiguration laden
 21 | try:
 22 |     config_file = Path.absolute(Path(__file__).parent.parent / "pgpt_openai_api_proxy.json")
 23 |     config = Config(config_file=config_file, required_fields=["base_url"])
 24 |     default_groups = config.get("groups", [])
 25 | except ConfigError as e:
 26 |     print(f"Configuration Error: {e}")
 27 |     exit(1)
 28 | 
 29 | 
 30 | 
 31 | @app.middleware("http")
 32 | async def store_request_headers(request: Request, call_next):
 33 |     request_context.headers = dict(request.headers)
 34 |     response = await call_next(request)
 35 |     return response
 36 | 
 37 | 
 38 | @app.post("/chat/completions")
 39 | async def chat_completions(request: ChatCompletionRequest):
 40 |     headers = getattr(request_context, "headers", {})
 41 |     client_api_key = str(headers['authorization']).split(" ")[1]
 42 |     groups = default_groups
 43 |     force_new_session = False
 44 | 
 45 |     if request.groups:
 46 |         groups = request.groups
 47 |     if request.newSession:
 48 |         force_new_session = True
 49 | 
 50 |     print("Groups: " + str(groups))
 51 | 
 52 |     if  request.messages:
 53 |         #Check if this api-key already has a running instance
 54 |         indices = [i for i, x in enumerate(instances) if
 55 |                    x.api_key == client_api_key]
 56 |         index = -1
 57 |         if len(indices) > 0:
 58 |             index = indices[0]
 59 |         if index > -1:
 60 |             # if we already have an instance, just reuse it. No need to open new connection
 61 |             if instances[index].agent.chosen_groups != groups:
 62 |                 print("⚠️ New Groups requested, switching to new Chat..")
 63 |                 config.set_value("groups", groups)
 64 |                 instances[index].agent.chat_id = None
 65 |             elif force_new_session:
 66 |                 print("⚠️ New Session Requested, switching to new Chat..")
 67 |                 config.set_value("groups", groups)
 68 |                 instances[index].agent.chat_id = None
 69 | 
 70 |             pgpt = instances[index].agent
 71 | 
 72 |         else:
 73 |             #otherwise connect via api-key
 74 |             config.set_value("groups", groups)
 75 |             pgpt = PrivateGPTAPI(config, client_api_key=client_api_key)
 76 |             # remember that we already have an instance for the api key
 77 |             instance = ChatInstance(client_api_key, pgpt)
 78 |             instances.append(instance)
 79 | 
 80 |         if pgpt.logged_in:
 81 |             response = pgpt.respond_with_context(request.messages, request.response_format, request.tools)
 82 |             if response is not None:
 83 |                 if "answer" not in response:
 84 |                     response["answer"] = "No Response received"
 85 |             if response is None or ("answer" in response and response["answer"] == "error"):
 86 |                    pgpt.login()
 87 |         else:
 88 |             response = {
 89 |                 "chatId": "0",
 90 |                 "answer": "API Key not valid",
 91 |             }
 92 |     else:
 93 |         response = {
 94 |             "chatId": "0",
 95 |             "answer": "No Input given",
 96 |         }
 97 | 
 98 |     if request.stream:
 99 |         return StreamingResponse(
100 |             _resp_async_generator(response, request), media_type="application/x-ndjson"
101 |         )
102 |     else:
103 |         return _resp_sync(response, request)
104 | 
105 | 
106 | # legacy completions API
107 | @app.post("/completions")
108 | async def completions(request: CompletionRequest):
109 |     headers = getattr(request_context, "headers", {})
110 |     client_api_key = str(headers['authorization']).split(" ")[1]
111 |     groups = default_groups
112 |     if request.groups:
113 |         groups = request.groups
114 |     print("Groups: " + str(groups))
115 |     if request.prompt:
116 | 
117 |         #otherwise connect via api-key
118 |         config.set_value("groups", groups)
119 |         pgpt = PrivateGPTAPI(config, client_api_key=client_api_key)
120 |         # remember that we already have an instance for the api key
121 | 
122 |         if pgpt.logged_in:
123 |             response = pgpt.respond_with_context([Message(role="user", content=request.prompt)], request.response_format, request.tools)
124 | 
125 |             if "answer" not in response:
126 |                 response["answer"] = "No Response received"
127 |             if "answer" in response and response["answer"] == "error":
128 |                 if pgpt.login():
129 |                     pgpt.create_chat()
130 |         else:
131 |             response = {
132 |                 "chatId": "0",
133 |                 "answer": "API Key not valid",
134 |             }
135 |     else:
136 |         response = {
137 |             "chatId": "0",
138 |             "answer": "No Input given",
139 |         }
140 | 
141 |     if request.stream :
142 |         return StreamingResponse(
143 |             _resp_async_generator_completions(response, request), media_type="application/x-ndjson"
144 |         )
145 |     else:
146 |         return _resp_sync_completions(response, request)
147 | 
148 | 
149 | 
150 | @app.get("/models")
151 | def return_models():
152 |     return {
153 |         "object": "list",
154 |         "data": models
155 |     }
156 | 
157 | 
158 | @app.get('/models/{model_id}')
159 | async def get_model(model_id: str):
160 |     filtered_entries = list(filter(lambda item: item["id"] == model_id, models))
161 |     entry = filtered_entries[0] if filtered_entries else None
162 |     print(entry)
163 |     if entry is None:
164 |             raise HTTPException(status_code=404, detail="Model not found")
165 |     return entry
166 | 
167 | 
168 | if __name__ == "__main__":
169 |     api_ip = config.get("api_ip", "0.0.0.0")
170 |     api_port = config.get("api_port", 8001)
171 |     uvicorn.run(app, host=api_ip, port=int(api_port))
172 | 
173 | 
174 | 
175 | 
```

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

```html
  1 | <!DOCTYPE html>
  2 | <html lang="de">
  3 | <head>
  4 |     <meta charset="UTF-8">
  5 |     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6 |     <title>ChatBot Agent Interface</title>
  7 |     <style>
  8 |         body {
  9 |             font-family: Arial, sans-serif;
 10 |             margin: 20px;
 11 |             padding: 0;
 12 |             background-color: #f4f4f9;
 13 |         }
 14 |         .container {
 15 |             max-width: 600px;
 16 |             margin: 0 auto;
 17 |             background: white;
 18 |             padding: 20px;
 19 |             border-radius: 8px;
 20 |             box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
 21 |             text-align: center; /* Zentriert den Inhalt */
 22 |         }
 23 |         .logo {
 24 |             display: block;
 25 |             margin: 0 auto 20px; /* Zentriert das Logo und fügt Abstand ein */
 26 |             width: 150px;
 27 |             height: auto;
 28 |         }
 29 |         h1 {
 30 |             text-align: center;
 31 |             color: #333;
 32 |         }
 33 |         textarea, select, input, button {
 34 |             width: 100%;
 35 |             margin: 10px 0;
 36 |             padding: 10px;
 37 |             font-size: 16px;
 38 |             border: 1px solid #ccc;
 39 |             border-radius: 5px;
 40 |             box-sizing: border-box;
 41 |         }
 42 |         button {
 43 |             background-color: #007BFF;
 44 |             color: white;
 45 |             border: none;
 46 |             cursor: pointer;
 47 |             font-size: 16px;
 48 |         }
 49 |         button:hover {
 50 |             background-color: #0056b3;
 51 |         }
 52 |         .response-box {
 53 |             margin-top: 20px;
 54 |             padding: 15px;
 55 |             border: 1px solid #ccc;
 56 |             border-radius: 5px;
 57 |             background-color: #f9f9f9;
 58 |             white-space: pre-wrap;
 59 |             font-family: monospace;
 60 |         }
 61 |     </style>
 62 | </head>
 63 | <body>
 64 |     <div class="container">
 65 |         <!-- Logo einfügen -->
 66 |         <img src="Logo_light.svg" alt="Logo" class="logo">
 67 | 
 68 |         <h1>ChatBot Agent</h1>
 69 | 
 70 |         <form id="queryForm">
 71 |             <label for="question">Question:</label>
 72 |             <textarea id="question" rows="3" placeholder="Enter your question here..." required></textarea>
 73 | 
 74 |             <label for="language">Language:</label>
 75 |             <select id="language">
 76 |                 <option value="en" selected>English</option>
 77 |                 <option value="de">German</option>
 78 |             </select>
 79 | 
 80 |             <label for="groups">Groups (optional, separated by commas):</label>
 81 |             <input type="text" id="groups" placeholder="Example: Group1, Group2">
 82 | 
 83 |             <label>
 84 |                 <input type="checkbox" id="usePublic" checked>
 85 |                 Use general knowledge
 86 |             </label>
 87 | 
 88 |             <button type="submit">Send Request</button>
 89 |         </form>
 90 | 
 91 |         <div class="response-box" id="responseBox">
 92 |             The response will be displayed here...
 93 |         </div>
 94 |     </div>
 95 | 
 96 |     <script>
 97 |         const apiUrl = "http://127.0.0.1:5001/ask"; // URL der API
 98 |         const apiKey = "IhrSichererAPIKey123"; // API-Key
 99 | 
100 |         document.getElementById("queryForm").addEventListener("submit", async function(event) {
101 |             event.preventDefault();
102 | 
103 |             // Eingaben aus dem Formular abrufen
104 |             const question = document.getElementById("question").value.trim();
105 |             const language = document.getElementById("language").value;
106 |             const groupsInput = document.getElementById("groups").value;
107 |             const groups = groupsInput
108 |                 .split(",")
109 |                 .map(group => group.trim())
110 |                 .filter(group => group); // Leere Gruppen entfernen
111 |             const usePublic = document.getElementById("usePublic").checked;
112 | 
113 |             if (!question) {
114 |                 alert("Please enter a question.");
115 |                 return;
116 |             }
117 | 
118 |             // JSON-Body für die Anfrage erstellen
119 |             const body = {
120 |                 question: question,
121 |                 usePublic: usePublic,
122 |                 groups: groups,
123 |                 language: language
124 |             };
125 | 
126 |             // Anzeige der Anfrage im Response-Box (optional)
127 |             document.getElementById("responseBox").textContent = "Sending request...";
128 | 
129 |             // Anfrage senden
130 |             try {
131 |                 const response = await fetch(apiUrl, {
132 |                     method: "POST",
133 |                     headers: {
134 |                         "Content-Type": "application/json",
135 |                         "X-API-KEY": apiKey // Korrigierter Header
136 |                     },
137 |                     body: JSON.stringify(body)
138 |                 });
139 | 
140 |                 if (response.ok) {
141 |                     const data = await response.json();
142 | 
143 |                     // Extrahiere das 'answer'-Feld und entferne mögliche Anführungszeichen
144 |                     let answer = data.answer || "";
145 |                     if (answer.startsWith('"') && answer.endsWith('"')) {
146 |                         answer = answer.substring(1, answer.length - 1);
147 |                     }
148 | 
149 |                     // Optional: Entschlüsselung von Unicode-Zeichen
150 |                     try {
151 |                         answer = decodeURIComponent(escape(answer));
152 |                     } catch (e) {
153 |                         console.warn("Unicode decoding failed:", e);
154 |                     }
155 | 
156 |                     // Anzeige der Antwort
157 |                     document.getElementById("responseBox").textContent = answer;
158 |                 } else {
159 |                     // Fehlerbehandlung bei HTTP-Fehlern
160 |                     const errorText = await response.text();
161 |                     document.getElementById("responseBox").textContent = `Error: ${response.status} ${response.statusText}\n${errorText}`;
162 |                 }
163 |             } catch (error) {
164 |                 // Fehlerbehandlung bei Netzwerk- oder anderen Fehlern
165 |                 document.getElementById("responseBox").textContent = `Request failed: ${error.message}`;
166 |             }
167 |         });
168 |     </script>
169 | </body>
170 | </html>
```

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

```html
  1 | <!DOCTYPE html>
  2 | <html lang="de">
  3 | <head>
  4 |     <meta charset="UTF-8">
  5 |     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6 |     <title>ChatBot Agent Interface</title>
  7 |     <style>
  8 |         body {
  9 |             font-family: Arial, sans-serif;
 10 |             margin: 20px;
 11 |             padding: 0;
 12 |             background-color: #f4f4f9;
 13 |         }
 14 |         .container {
 15 |             max-width: 600px;
 16 |             margin: 0 auto;
 17 |             background: white;
 18 |             padding: 20px;
 19 |             border-radius: 8px;
 20 |             box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
 21 |             text-align: center; /* Zentriert den Inhalt */
 22 |         }
 23 |         .logo {
 24 |             display: block;
 25 |             margin: 0 auto 20px; /* Zentriert das Logo und fügt Abstand ein */
 26 |             width: 150px;
 27 |             height: auto;
 28 |         }
 29 |         h1 {
 30 |             text-align: center;
 31 |             color: #333;
 32 |         }
 33 |         textarea, select, input, button {
 34 |             width: 100%;
 35 |             margin: 10px 0;
 36 |             padding: 10px;
 37 |             font-size: 16px;
 38 |             border: 1px solid #ccc;
 39 |             border-radius: 5px;
 40 |             box-sizing: border-box;
 41 |         }
 42 |         button {
 43 |             background-color: #007BFF;
 44 |             color: white;
 45 |             border: none;
 46 |             cursor: pointer;
 47 |             font-size: 16px;
 48 |         }
 49 |         button:hover {
 50 |             background-color: #0056b3;
 51 |         }
 52 |         .response-box {
 53 |             margin-top: 20px;
 54 |             padding: 15px;
 55 |             border: 1px solid #ccc;
 56 |             border-radius: 5px;
 57 |             background-color: #f9f9f9;
 58 |             white-space: pre-wrap;
 59 |             font-family: monospace;
 60 |         }
 61 |     </style>
 62 | </head>
 63 | <body>
 64 |     <div class="container">
 65 |         <!-- Logo einfügen -->
 66 |         <img src="Logo_light.svg" alt="Logo" class="logo">
 67 | 
 68 |         <h1>ChatBot Agent</h1>
 69 | 
 70 |         <form id="queryForm">
 71 |             <label for="question">Frage:</label>
 72 |             <textarea id="question" rows="3" placeholder="Geben Sie Ihre Frage ein..." required></textarea>
 73 | 
 74 |             <label for="language">Sprache:</label>
 75 |             <select id="language">
 76 |                 <option value="de" selected>Deutsch</option>
 77 |                 <option value="en">Englisch</option>
 78 |             </select>
 79 | 
 80 |             <label for="groups">Gruppen (optional, getrennt durch Kommas):</label>
 81 |             <input type="text" id="groups" placeholder="Beispiel: Gruppe1, Gruppe2">
 82 | 
 83 |             <label>
 84 |                 <input type="checkbox" id="usePublic" checked>
 85 |                 Öffentliche Daten verwenden
 86 |             </label>
 87 | 
 88 |             <button type="submit">Anfrage senden</button>
 89 |         </form>
 90 | 
 91 |         <div class="response-box" id="responseBox">
 92 |             Antwort wird hier angezeigt...
 93 |         </div>
 94 |     </div>
 95 | 
 96 |     <script>
 97 |         const apiUrl = "http://192.168.100.185:5001/ask"; // URL der API
 98 |         const apiKey = "IhrSichererAPIKey123"; // API-Key
 99 | 
100 |         document.getElementById("queryForm").addEventListener("submit", async function(event) {
101 |             event.preventDefault();
102 | 
103 |             // Eingaben aus dem Formular abrufen
104 |             const question = document.getElementById("question").value.trim();
105 |             const language = document.getElementById("language").value;
106 |             const groupsInput = document.getElementById("groups").value;
107 |             const groups = groupsInput
108 |                 .split(",")
109 |                 .map(group => group.trim())
110 |                 .filter(group => group); // Leere Gruppen entfernen
111 |             const usePublic = document.getElementById("usePublic").checked;
112 | 
113 |             if (!question) {
114 |                 alert("Bitte geben Sie eine Frage ein.");
115 |                 return;
116 |             }
117 | 
118 |             // JSON-Body für die Anfrage erstellen
119 |             const body = {
120 |                 question: question,
121 |                 usePublic: usePublic,
122 |                 groups: groups,
123 |                 language: language
124 |             };
125 | 
126 |             // Anzeige der Anfrage im Response-Box (optional)
127 |             document.getElementById("responseBox").textContent = "Anfrage wird gesendet...";
128 | 
129 |             // Anfrage senden
130 |             try {
131 |                 const response = await fetch(apiUrl, {
132 |                     method: "POST",
133 |                     headers: {
134 |                         "Content-Type": "application/json",
135 |                         "X-API-KEY": apiKey // Korrigierter Header
136 |                     },
137 |                     body: JSON.stringify(body)
138 |                 });
139 | 
140 |                 if (response.ok) {
141 |                     const data = await response.json();
142 | 
143 |                     // Extrahiere das 'answer'-Feld und entferne mögliche Anführungszeichen
144 |                     let answer = data.answer || "";
145 |                     if (answer.startsWith('"') && answer.endsWith('"')) {
146 |                         answer = answer.substring(1, answer.length - 1);
147 |                     }
148 | 
149 |                     // Optional: Entschlüsselung von Unicode-Zeichen
150 |                     try {
151 |                         answer = decodeURIComponent(escape(answer));
152 |                     } catch (e) {
153 |                         console.warn("Unicode-Entschlüsselung fehlgeschlagen:", e);
154 |                     }
155 | 
156 |                     // Anzeige der Antwort
157 |                     document.getElementById("responseBox").textContent = answer;
158 |                 } else {
159 |                     // Fehlerbehandlung bei HTTP-Fehlern
160 |                     const errorText = await response.text();
161 |                     document.getElementById("responseBox").textContent = `Fehler: ${response.status} ${response.statusText}\n${errorText}`;
162 |                 }
163 |             } catch (error) {
164 |                 // Fehlerbehandlung bei Netzwerk- oder anderen Fehlern
165 |                 document.getElementById("responseBox").textContent = `Fehler bei der Anfrage: ${error.message}`;
166 |             }
167 |         });
168 |     </script>
169 | </body>
170 | </html>
171 | 
```

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

```java
  1 | import org.json.JSONArray;
  2 | import org.json.JSONObject;
  3 | 
  4 | import java.io.IOException;
  5 | import java.io.InputStream;
  6 | import java.io.OutputStream;
  7 | import java.net.Socket;
  8 | import java.nio.charset.StandardCharsets;
  9 | import java.util.ArrayList;
 10 | import java.util.Arrays;
 11 | import java.util.List;
 12 | 
 13 | public class MCPEditSourceClient {
 14 | 
 15 |     public static void main(String[] args) {
 16 |         // Mindestens 8 Strings im Array erforderlich, z.B.:
 17 |         // --server-ip 127.0.0.1 --server-port 1234 --token X --source-id Y
 18 |         // plus optionale: --title "..." --content "..." --groups ...
 19 |         if (args.length < 8) {
 20 |             printUsage();
 21 |             return;
 22 |         }
 23 | 
 24 |         // Argumente einlesen
 25 |         String serverIp   = getArgument(args, "--server-ip");
 26 |         String portStr    = getArgument(args, "--server-port");
 27 |         String token      = getArgument(args, "--token");
 28 |         String sourceId   = getArgument(args, "--source-id");
 29 |         String title      = getArgument(args, "--title");
 30 |         String content    = getArgument(args, "--content");
 31 |         List<String> groups = getListArgument(args, "--groups");
 32 | 
 33 |         // Prüfung auf null
 34 |         if (serverIp == null || portStr == null || token == null || sourceId == null) {
 35 |             System.out.println("Fehler: Mindestens eines der Pflichtargumente fehlt.");
 36 |             return;
 37 |         }
 38 | 
 39 |         // Port in int umwandeln
 40 |         int serverPort;
 41 |         try {
 42 |             serverPort = Integer.parseInt(portStr);
 43 |         } catch (NumberFormatException e) {
 44 |             System.out.println("Fehler: --server-port muss eine ganzzahlige Portangabe sein.");
 45 |             return;
 46 |         }
 47 | 
 48 |         System.out.println("📤 Sende Anfrage zum Editieren einer Quelle...");
 49 | 
 50 |         // Anfrage an den Server senden
 51 |         String response = sendEditSourceRequest(serverIp, serverPort, token, sourceId, title, content, groups);
 52 | 
 53 |         // Antwort ausgeben
 54 |         System.out.println("Response from server:");
 55 |         System.out.println(response);
 56 |     }
 57 | 
 58 |     /**
 59 |      * Baut die Payload für die "edit_source"-Anfrage zusammen und sendet sie über TCP.
 60 |      */
 61 |     private static String sendEditSourceRequest(
 62 |             String serverIp,
 63 |             int serverPort,
 64 |             String token,
 65 |             String sourceId,
 66 |             String title,
 67 |             String content,
 68 |             List<String> groups
 69 |     ) {
 70 |         // Arguments-Objekt erstellen
 71 |         JSONObject arguments = new JSONObject();
 72 |         arguments.put("sourceId", sourceId);
 73 | 
 74 |         if (title != null && !title.trim().isEmpty()) {
 75 |             arguments.put("title", title);
 76 |         }
 77 | 
 78 |         if (content != null && !content.trim().isEmpty()) {
 79 |             arguments.put("content", content);
 80 |         }
 81 | 
 82 |         // Gruppen (falls keine übergeben, bleibt es einfach eine leere Liste)
 83 |         if (groups == null) {
 84 |             groups = new ArrayList<>();
 85 |         }
 86 |         JSONArray groupsArray = new JSONArray(groups);
 87 |         arguments.put("groups", groupsArray);
 88 | 
 89 |         // Gesamte Payload
 90 |         JSONObject payload = new JSONObject();
 91 |         payload.put("command", "edit_source");
 92 |         payload.put("token", token);
 93 |         payload.put("arguments", arguments);
 94 | 
 95 |         // JSON in String umwandeln
 96 |         String payloadJson = payload.toString();
 97 | 
 98 |         // TCP-Verbindung aufbauen und senden
 99 |         try (Socket client = new Socket(serverIp, serverPort)) {
100 |             // Senden
101 |             OutputStream out = client.getOutputStream();
102 |             byte[] data = payloadJson.getBytes(StandardCharsets.UTF_8);
103 |             out.write(data);
104 |             out.flush();
105 | 
106 |             // Antwort empfangen
107 |             InputStream in = client.getInputStream();
108 |             byte[] buffer = new byte[4096];
109 |             StringBuilder responseBuilder = new StringBuilder();
110 | 
111 |             int bytesRead;
112 |             do {
113 |                 bytesRead = in.read(buffer);
114 |                 if (bytesRead > 0) {
115 |                     responseBuilder.append(new String(buffer, 0, bytesRead, StandardCharsets.UTF_8));
116 |                 }
117 |             } while (bytesRead == buffer.length);
118 | 
119 |             return responseBuilder.toString();
120 | 
121 |         } catch (IOException e) {
122 |             return "Error: " + e.getMessage();
123 |         }
124 |     }
125 | 
126 |     /**
127 |      * Liest den Wert für ein bestimmtes Argument aus (z.B. --server-ip 127.0.0.1).
128 |      */
129 |     private static String getArgument(String[] args, String key) {
130 |         for (int i = 0; i < args.length - 1; i++) {
131 |             if (args[i].equals(key)) {
132 |                 return args[i + 1];
133 |             }
134 |         }
135 |         return null;
136 |     }
137 | 
138 |     /**
139 |      * Liest eine Liste von Werten aus (z.B. --groups G1 G2 G3 ...), bis zum nächsten -- oder Ende.
140 |      */
141 |     private static List<String> getListArgument(String[] args, String key) {
142 |         List<String> result = new ArrayList<>();
143 |         for (int i = 0; i < args.length; i++) {
144 |             if (args[i].equals(key)) {
145 |                 // Ab hier Werte einsammeln
146 |                 for (int j = i + 1; j < args.length; j++) {
147 |                     if (args[j].startsWith("--")) {
148 |                         break;
149 |                     }
150 |                     result.add(args[j]);
151 |                 }
152 |                 break;
153 |             }
154 |         }
155 |         return result;
156 |     }
157 | 
158 |     private static void printUsage() {
159 |         System.out.println("Usage:");
160 |         System.out.println("  --server-ip <IP> --server-port <PORT> --token <TOKEN> --source-id <SOURCE_ID>");
161 |         System.out.println("  [--title <TITLE>] [--content <CONTENT>] [--groups <LIST_OF_GROUPS>]");
162 |         System.out.println();
163 |         System.out.println("Example:");
164 |         System.out.println("  java -cp .;json-20241224.jar MCPEditSourceClient \\");
165 |         System.out.println("       --server-ip 127.0.0.1 --server-port 1234 --token SomeToken --source-id 456 \\");
166 |         System.out.println("       --title \"Neuer Titel\" --content \"Neuer Inhalt...\" --groups DevOps Finance");
167 |     }
168 | }
169 | 
```

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

```php
  1 | <?php
  2 | /**
  3 |  * MCPKeygenClient.php
  4 |  *
  5 |  * A PHP script that acts as a Keygen Client. It connects to a server via TCP,
  6 |  * sends a keygen request, and receives the server's response.
  7 |  *
  8 |  * Usage:
  9 |  * php MCPKeygenClient.php --server-ip <IP> --server-port <Port> --token <Token> --password <Password>
 10 |  */
 11 | 
 12 | /**
 13 |  * Function to parse command line arguments
 14 |  *
 15 |  * @param array $args The command line arguments
 16 |  * @return array An associative array with the parsed arguments
 17 |  */
 18 | function parseArguments($args) {
 19 |     $parsedArgs = [];
 20 |     $argc = count($args);
 21 |     for ($i = 1; $i < $argc; $i++) {
 22 |         switch ($args[$i]) {
 23 |             case '--server-ip':
 24 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 25 |                     $parsedArgs['serverIp'] = $args[++$i];
 26 |                 } else {
 27 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --server-ip.\n");
 28 |                 }
 29 |                 break;
 30 |             case '--server-port':
 31 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 32 |                     $parsedArgs['serverPort'] = intval($args[++$i]);
 33 |                 } else {
 34 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --server-port.\n");
 35 |                 }
 36 |                 break;
 37 |             case '--token':
 38 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 39 |                     $parsedArgs['token'] = $args[++$i];
 40 |                 } else {
 41 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --token.\n");
 42 |                 }
 43 |                 break;
 44 |             case '--password':
 45 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 46 |                     $parsedArgs['password'] = $args[++$i];
 47 |                 } else {
 48 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --password.\n");
 49 |                 }
 50 |                 break;
 51 |             default:
 52 |                 fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
 53 |         }
 54 |     }
 55 |     return $parsedArgs;
 56 | }
 57 | 
 58 | /**
 59 |  * Helper function to check if a string starts with a specific prefix
 60 |  *
 61 |  * @param string $string The string to check
 62 |  * @param string $prefix The prefix
 63 |  * @return bool True if the string starts with the prefix, otherwise False
 64 |  */
 65 | function startsWith($string, $prefix) {
 66 |     return substr($string, 0, strlen($prefix)) === $prefix;
 67 | }
 68 | 
 69 | /**
 70 |  * Function to send a Keygen request over a TCP connection
 71 |  *
 72 |  * @param string $serverIp The server's IP address
 73 |  * @param int $serverPort The server's port
 74 |  * @param string $token The authentication token
 75 |  * @param string $password The password for key generation
 76 |  * @return array The response received from the server as an associative array
 77 |  * @throws Exception On connection errors or JSON parsing errors
 78 |  */
 79 | function sendKeygenRequest($serverIp, $serverPort, $token, $password) {
 80 |     $payload = [
 81 |         "command" => "keygen",
 82 |         "token" => $token,
 83 |         "arguments" => [
 84 |             "password" => $password
 85 |         ]
 86 |     ];
 87 | 
 88 |     $jsonPayload = json_encode($payload);
 89 |     if ($jsonPayload === false) {
 90 |         throw new Exception("Error encoding JSON payload: " . json_last_error_msg());
 91 |     }
 92 | 
 93 |     $errno = 0;
 94 |     $errstr = '';
 95 |     $timeoutDuration = 10; // Seconds (10 seconds timeout)
 96 |     $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);
 97 | 
 98 |     if (!$client) {
 99 |         throw new Exception("Connection error: $errstr ($errno)");
100 |     }
101 | 
102 |     echo "🔗 Connected to server ({$serverIp}:{$serverPort}).\n";
103 |     echo "📤 Sending Payload: {$jsonPayload}\n";
104 | 
105 |     fwrite($client, $jsonPayload);
106 | 
107 |     $responseData = '';
108 |     stream_set_timeout($client, $timeoutDuration);
109 | 
110 |     while (!feof($client)) {
111 |         $data = fread($client, 1024);
112 |         if ($data === false) {
113 |             throw new Exception("Error reading data from server.");
114 |         }
115 |         if ($data === '') {
116 |             break; // No more data
117 |         }
118 |         echo "📥 Received data: {$data}\n";
119 |         $responseData .= $data;
120 | 
121 |         // Attempt to parse the received data as JSON
122 |         $parsedData = json_decode($responseData, true);
123 |         if ($parsedData !== null) {
124 |             echo "✅ JSON response successfully parsed.\n";
125 |             fclose($client);
126 |             return $parsedData;
127 |         }
128 | 
129 |         // Check if the stream has timed out
130 |         $info = stream_get_meta_data($client);
131 |         if ($info['timed_out']) {
132 |             throw new Exception("Timeout while waiting for data from server.");
133 |         }
134 |     }
135 | 
136 |     fclose($client);
137 |     throw new Exception("Connection to server was closed before a complete response was received.");
138 | }
139 | 
140 | /**
141 |  * Main function of the script
142 |  */
143 | function main($argv) {
144 |     $parsedArgs = parseArguments($argv);
145 |     $serverIp = $parsedArgs['serverIp'] ?? null;
146 |     $serverPort = $parsedArgs['serverPort'] ?? null;
147 |     $token = $parsedArgs['token'] ?? null;
148 |     $password = $parsedArgs['password'] ?? null;
149 | 
150 |     // Check if all required parameters are present
151 |     if (!$serverIp || !$serverPort || !$token || !$password) {
152 |         fwrite(STDERR, "❌ Error: --server-ip, --server-port, --token, and --password are required.\n");
153 |         fwrite(STDOUT, "📖 Usage: php MCPKeygenClient.php --server-ip <IP> --server-port <Port> --token <Token> --password <Password>\n");
154 |         exit(1);
155 |     }
156 | 
157 |     try {
158 |         echo "🔑 Sending Keygen request...\n";
159 |         $response = sendKeygenRequest(
160 |             $serverIp,
161 |             $serverPort,
162 |             $token,
163 |             $password
164 |         );
165 |         echo "✔️ Server response:\n";
166 |         echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
167 |     } catch (Exception $e) {
168 |         fwrite(STDERR, "❌ Error during Keygen request: " . $e->getMessage() . "\n");
169 |     }
170 | }
171 | 
172 | // Check if PHP version is at least 7.1 (for better features)
173 | if (version_compare(PHP_VERSION, '7.1.0') < 0) {
174 |     fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
175 |     exit(1);
176 | }
177 | 
178 | // Call the main function
179 | main($argv);
180 | ?>
181 | 
```

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

```javascript
  1 | <?php
  2 | /**
  3 |  * MCPDeleteUserClient.php
  4 |  *
  5 |  * A PHP script that acts as a Delete User Client. It connects to a server via TCP,
  6 |  * sends a request to delete an existing user, and receives the server's response.
  7 |  *
  8 |  * Usage:
  9 |  * php MCPDeleteUserClient.php --server-ip <IP> --server-port <Port> --email <Email> --token <Token>
 10 |  */
 11 | 
 12 | /**
 13 |  * Function to parse command line arguments
 14 |  *
 15 |  * @param array $args Array of command line arguments
 16 |  * @return array Associative array with parsed arguments
 17 |  */
 18 | function parseArguments($args) {
 19 |     $parsedArgs = [];
 20 |     $argc = count($args);
 21 |     for ($i = 1; $i < $argc; $i++) {
 22 |         switch ($args[$i]) {
 23 |             case '--server-ip':
 24 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 25 |                     $parsedArgs['serverIp'] = $args[++$i];
 26 |                 } else {
 27 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --server-ip.\n");
 28 |                 }
 29 |                 break;
 30 |             case '--server-port':
 31 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 32 |                     $parsedArgs['serverPort'] = intval($args[++$i]);
 33 |                 } else {
 34 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --server-port.\n");
 35 |                 }
 36 |                 break;
 37 |             case '--email':
 38 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 39 |                     $parsedArgs['email'] = $args[++$i];
 40 |                 } else {
 41 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --email.\n");
 42 |                 }
 43 |                 break;
 44 |             case '--token':
 45 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 46 |                     $parsedArgs['token'] = $args[++$i];
 47 |                 } else {
 48 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --token.\n");
 49 |                 }
 50 |                 break;
 51 |             default:
 52 |                 fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
 53 |         }
 54 |     }
 55 |     return $parsedArgs;
 56 | }
 57 | 
 58 | /**
 59 |  * Helper function to check if a string starts with a specific prefix
 60 |  *
 61 |  * @param string $string The string to check
 62 |  * @param string $prefix The prefix
 63 |  * @return bool True if the string starts with the prefix, otherwise False
 64 |  */
 65 | function startsWith($string, $prefix) {
 66 |     return substr($string, 0, strlen($prefix)) === $prefix;
 67 | }
 68 | 
 69 | /**
 70 |  * Function to send a Delete User request over a TCP connection
 71 |  *
 72 |  * @param string $serverIp The server's IP address
 73 |  * @param int $serverPort The server's port
 74 |  * @param string $email The email of the user to be deleted
 75 |  * @param string $token The authentication token
 76 |  * @return array The response received from the server as an associative array
 77 |  * @throws Exception On connection errors or JSON parsing errors
 78 |  */
 79 | function sendDeleteUserRequest($serverIp, $serverPort, $email, $token) {
 80 |     $payload = [
 81 |         "command" => "delete_user",
 82 |         "token" => $token,
 83 |         "arguments" => [
 84 |             "email" => $email
 85 |         ]
 86 |     ];
 87 | 
 88 |     $jsonPayload = json_encode($payload);
 89 |     if ($jsonPayload === false) {
 90 |         throw new Exception("Error while encoding the JSON payload: " . json_last_error_msg());
 91 |     }
 92 | 
 93 |     $errno = 0;
 94 |     $errstr = '';
 95 |     $timeoutDuration = 10; // Seconds (10 seconds timeout)
 96 |     $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);
 97 | 
 98 |     if (!$client) {
 99 |         throw new Exception("Connection error: $errstr ($errno)");
100 |     }
101 | 
102 |     echo "🔗 Connected to server ({$serverIp}:{$serverPort}).\n";
103 |     echo "📤 Sending Payload: {$jsonPayload}\n";
104 | 
105 |     fwrite($client, $jsonPayload);
106 | 
107 |     $responseData = '';
108 |     stream_set_timeout($client, $timeoutDuration);
109 | 
110 |     while (!feof($client)) {
111 |         $data = fread($client, 1024);
112 |         if ($data === false) {
113 |             throw new Exception("Error reading data from server.");
114 |         }
115 |         if ($data === '') {
116 |             break; // No more data
117 |         }
118 |         echo "📥 Received data: {$data}\n";
119 |         $responseData .= $data;
120 | 
121 |         // Attempt to parse the received data as JSON
122 |         $parsedData = json_decode($responseData, true);
123 |         if ($parsedData !== null) {
124 |             echo "✅ JSON response successfully parsed.\n";
125 |             fclose($client);
126 |             return $parsedData;
127 |         }
128 | 
129 |         // Check if the stream has timed out
130 |         $info = stream_get_meta_data($client);
131 |         if ($info['timed_out']) {
132 |             throw new Exception("Timeout while waiting for data from server.");
133 |         }
134 |     }
135 | 
136 |     fclose($client);
137 |     throw new Exception("Connection to server was closed before a complete response was received.");
138 | }
139 | 
140 | /**
141 |  * Main function of the script
142 |  */
143 | function main($argv) {
144 |     $parsedArgs = parseArguments($argv);
145 |     $serverIp = $parsedArgs['serverIp'] ?? null;
146 |     $serverPort = $parsedArgs['serverPort'] ?? null;
147 |     $email = $parsedArgs['email'] ?? null;
148 |     $token = $parsedArgs['token'] ?? null;
149 | 
150 |     // Check if all required parameters are present
151 |     if (!$serverIp || !$serverPort || !$email || !$token) {
152 |         fwrite(STDERR, "❌ ERROR: --server-ip, --server-port, --email, and --token are required.\n");
153 |         fwrite(STDOUT, "📖 Example: php MCPDeleteUserClient.php --server-ip 192.168.0.1 --server-port 5000 --email [email protected] --token YOUR_AUTH_TOKEN\n");
154 |         exit(1);
155 |     }
156 | 
157 |     try {
158 |         echo "🗑️ Sending Delete-User request...\n";
159 |         $response = sendDeleteUserRequest(
160 |             $serverIp,
161 |             $serverPort,
162 |             $email,
163 |             $token
164 |         );
165 |         echo "✔️ Server response:\n";
166 |         echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
167 |     } catch (Exception $e) {
168 |         fwrite(STDERR, "❌ Error deleting user: " . $e->getMessage() . "\n");
169 |     }
170 | }
171 | 
172 | // Check if PHP version is at least 7.1 (for better features)
173 | if (version_compare(PHP_VERSION, '7.1.0') < 0) {
174 |     fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
175 |     exit(1);
176 | }
177 | 
178 | // Call the main function
179 | main($argv);
180 | ?>
181 | 
```

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

```php
  1 | <?php
  2 | /**
  3 |  * MCPDeleteUserClient.php
  4 |  *
  5 |  * A PHP script that acts as a Delete User Client. It connects to a server via TCP,
  6 |  * sends a request to delete an existing user, and receives the server's response.
  7 |  *
  8 |  * Usage:
  9 |  * php MCPDeleteUserClient.php --server-ip <IP> --server-port <Port> --email <Email> --token <Token>
 10 |  */
 11 | 
 12 | /**
 13 |  * Function to parse command line arguments
 14 |  *
 15 |  * @param array $args Array of command line arguments
 16 |  * @return array Associative array with parsed arguments
 17 |  */
 18 | function parseArguments($args) {
 19 |     $parsedArgs = [];
 20 |     $argc = count($args);
 21 |     for ($i = 1; $i < $argc; $i++) {
 22 |         switch ($args[$i]) {
 23 |             case '--server-ip':
 24 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 25 |                     $parsedArgs['serverIp'] = $args[++$i];
 26 |                 } else {
 27 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --server-ip.\n");
 28 |                 }
 29 |                 break;
 30 |             case '--server-port':
 31 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 32 |                     $parsedArgs['serverPort'] = intval($args[++$i]);
 33 |                 } else {
 34 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --server-port.\n");
 35 |                 }
 36 |                 break;
 37 |             case '--email':
 38 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 39 |                     $parsedArgs['email'] = $args[++$i];
 40 |                 } else {
 41 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --email.\n");
 42 |                 }
 43 |                 break;
 44 |             case '--token':
 45 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 46 |                     $parsedArgs['token'] = $args[++$i];
 47 |                 } else {
 48 |                     fwrite(STDERR, "⚠️ Warning: No value provided for --token.\n");
 49 |                 }
 50 |                 break;
 51 |             default:
 52 |                 fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
 53 |         }
 54 |     }
 55 |     return $parsedArgs;
 56 | }
 57 | 
 58 | /**
 59 |  * Helper function to check if a string starts with a specific prefix
 60 |  *
 61 |  * @param string $string The string to check
 62 |  * @param string $prefix The prefix
 63 |  * @return bool True if the string starts with the prefix, otherwise False
 64 |  */
 65 | function startsWith($string, $prefix) {
 66 |     return substr($string, 0, strlen($prefix)) === $prefix;
 67 | }
 68 | 
 69 | /**
 70 |  * Function to send a Delete User request over a TCP connection
 71 |  *
 72 |  * @param string $serverIp The server's IP address
 73 |  * @param int $serverPort The server's port
 74 |  * @param string $email The email of the user to be deleted
 75 |  * @param string $token The authentication token
 76 |  * @return array The response received from the server as an associative array
 77 |  * @throws Exception On connection errors or JSON parsing errors
 78 |  */
 79 | function sendDeleteUserRequest($serverIp, $serverPort, $email, $token) {
 80 |     $payload = [
 81 |         "command" => "delete_user",
 82 |         "token" => $token,
 83 |         "arguments" => [
 84 |             "email" => $email
 85 |         ]
 86 |     ];
 87 | 
 88 |     $jsonPayload = json_encode($payload);
 89 |     if ($jsonPayload === false) {
 90 |         throw new Exception("Error while encoding the JSON payload: " . json_last_error_msg());
 91 |     }
 92 | 
 93 |     $errno = 0;
 94 |     $errstr = '';
 95 |     $timeoutDuration = 10; // Seconds (10 seconds timeout)
 96 |     $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);
 97 | 
 98 |     if (!$client) {
 99 |         throw new Exception("Connection error: $errstr ($errno)");
100 |     }
101 | 
102 |     echo "🔗 Connected to server ({$serverIp}:{$serverPort}).\n";
103 |     echo "📤 Sending Payload: {$jsonPayload}\n";
104 | 
105 |     fwrite($client, $jsonPayload);
106 | 
107 |     $responseData = '';
108 |     stream_set_timeout($client, $timeoutDuration);
109 | 
110 |     while (!feof($client)) {
111 |         $data = fread($client, 1024);
112 |         if ($data === false) {
113 |             throw new Exception("Error reading data from server.");
114 |         }
115 |         if ($data === '') {
116 |             break; // No more data
117 |         }
118 |         echo "📥 Received data: {$data}\n";
119 |         $responseData .= $data;
120 | 
121 |         // Attempt to parse the received data as JSON
122 |         $parsedData = json_decode($responseData, true);
123 |         if ($parsedData !== null) {
124 |             echo "✅ JSON response successfully parsed.\n";
125 |             fclose($client);
126 |             return $parsedData;
127 |         }
128 | 
129 |         // Check if the stream has timed out
130 |         $info = stream_get_meta_data($client);
131 |         if ($info['timed_out']) {
132 |             throw new Exception("Timeout while waiting for data from server.");
133 |         }
134 |     }
135 | 
136 |     fclose($client);
137 |     throw new Exception("Connection to server was closed before a complete response was received.");
138 | }
139 | 
140 | /**
141 |  * Main function of the script
142 |  */
143 | function main($argv) {
144 |     $parsedArgs = parseArguments($argv);
145 |     $serverIp = $parsedArgs['serverIp'] ?? null;
146 |     $serverPort = $parsedArgs['serverPort'] ?? null;
147 |     $email = $parsedArgs['email'] ?? null;
148 |     $token = $parsedArgs['token'] ?? null;
149 | 
150 |     // Check if all required parameters are present
151 |     if (!$serverIp || !$serverPort || !$email || !$token) {
152 |         fwrite(STDERR, "❌ ERROR: --server-ip, --server-port, --email, and --token are required.\n");
153 |         fwrite(STDOUT, "📖 Example: php MCPDeleteUserClient.php --server-ip 192.168.0.1 --server-port 5000 --email [email protected] --token YOUR_AUTH_TOKEN\n");
154 |         exit(1);
155 |     }
156 | 
157 |     try {
158 |         echo "🗑️ Sending Delete-User request...\n";
159 |         $response = sendDeleteUserRequest(
160 |             $serverIp,
161 |             $serverPort,
162 |             $email,
163 |             $token
164 |         );
165 |         echo "✔️ Server response:\n";
166 |         echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
167 |     } catch (Exception $e) {
168 |         fwrite(STDERR, "❌ Error deleting user: " . $e->getMessage() . "\n");
169 |     }
170 | }
171 | 
172 | // Check if PHP version is at least 7.1 (for better features)
173 | if (version_compare(PHP_VERSION, '7.1.0') < 0) {
174 |     fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
175 |     exit(1);
176 | }
177 | 
178 | // Call the main function
179 | main($argv);
180 | ?>
181 | 
```

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

```python
  1 | import socket
  2 | import ssl
  3 | import json
  4 | import logging
  5 | import time
  6 | from .language import languages
  7 | 
  8 | class NetworkError(Exception):
  9 |     pass
 10 | 
 11 | class NetworkClient:
 12 |     def __init__(
 13 |         self, server_ip, server_port, language="en",
 14 |         retries=3, delay=5, use_ssl=True, accept_self_signed=True
 15 |     ):
 16 |         self.server_ip = server_ip
 17 |         self.server_port = server_port
 18 |         self.retries = retries
 19 |         self.delay = delay
 20 |         self.use_ssl = use_ssl
 21 |         self.accept_self_signed = accept_self_signed
 22 |         self.language = language if language in languages else "en"
 23 |         self.lang = languages[self.language]
 24 | 
 25 |     def get_lang_message(self, key, **kwargs):
 26 |         """
 27 |         Secure method to retrieve messages from the language dictionary.
 28 |         Returns a default message if the key does not exist.
 29 |         """
 30 |         message = self.lang.get(key, "Message not defined.")
 31 |         utf8_encoded_string = bytes(message, 'utf-8')
 32 |         message = str(utf8_encoded_string, 'utf-8')
 33 |         try:
 34 |             return message.format(**kwargs)
 35 |         except KeyError as e:
 36 |             logging.error(f"Missing placeholder in language file for key '{key}': {e}")
 37 |             return message
 38 | 
 39 |     def send_request(self, payload):
 40 |         payload_json = json.dumps(payload)
 41 |         #logging.info(f"Prepared payload: {payload_json}")
 42 | 
 43 |         for attempt in range(1, self.retries + 1):
 44 |             client_socket = None
 45 |             try:
 46 |                 raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 47 |                 raw_socket.settimeout(30)
 48 |                 
 49 |                 logging.info(
 50 |                     self.get_lang_message(
 51 |                         "connecting_to_server",
 52 |                         ip=self.server_ip,
 53 |                         port=self.server_port,
 54 |                         attempt=attempt,
 55 |                         retries=self.retries
 56 |                     )
 57 |                 )
 58 |                 
 59 |                 # SSL/TLS initialisieren (falls gewünscht)
 60 |                 if self.use_ssl:
 61 |                     context = ssl.create_default_context()
 62 |                     if self.accept_self_signed:
 63 |                         context.check_hostname = False
 64 |                         context.verify_mode = ssl.CERT_NONE
 65 |                     client_socket = context.wrap_socket(raw_socket, server_hostname=self.server_ip)
 66 |                 else:
 67 |                     client_socket = raw_socket
 68 |                 
 69 |                 # Verbinden
 70 |                 client_socket.connect((self.server_ip, self.server_port))
 71 |                 logging.info(self.get_lang_message("connection_established"))
 72 |                 
 73 |                 # Anfrage senden
 74 |                 #logging.info(
 75 |                 #    self.get_lang_message(
 76 |                 #        "sending_payload",
 77 |                 #        payload=payload_json
 78 |                 #    )
 79 |                 #)
 80 |                 client_socket.sendall((payload_json + '\n').encode("utf-8"))
 81 |                 
 82 |                 # Alle Daten empfangen, bis Server von sich aus schließt oder Timeout
 83 |                 response = b""
 84 |                 while True:
 85 |                     try:
 86 |                         part = client_socket.recv(4096)
 87 |                         if not part:
 88 |                             # Keine Daten mehr -> Server hat Verbindung geschlossen
 89 |                             break
 90 |                         response += part
 91 |                     except socket.timeout:
 92 |                         # Wenn wir hier sicher sind, dass keine weiteren Daten mehr kommen,
 93 |                         # kann man das Lesen beenden. Oder retry. Je nach Protokoll.
 94 |                         logging.warning(self.get_lang_message("connection_timed_out"))
 95 |                         break
 96 |                 
 97 |                 decoded = response.decode("utf-8").strip()
 98 |                 #logging.info(f"Received response: {decoded}")
 99 |                 
100 |                 if not decoded:
101 |                     raise ValueError("Empty response received")
102 | 
103 |                 # JSON parsen
104 |                 try:
105 |                     parsed_response = json.loads(decoded)
106 |                     logging.info(
107 |                         self.get_lang_message("formatted_response"),
108 |                         extra={"data": parsed_response}
109 |                     )
110 |                     
111 |                     if "data" in parsed_response and "personalGroups" in parsed_response["data"]:
112 |                         personal_groups = parsed_response["data"]["personalGroups"]
113 |                         logging.info(
114 |                             self.get_lang_message("personal_groups_received", groups=personal_groups)
115 |                         )
116 |                     
117 |                     # Erfolgreich -> Socket normal schließen und Ergebnis zurückgeben
118 |                     client_socket.close()
119 |                     return parsed_response
120 | 
121 |                 except json.JSONDecodeError:
122 |                     logging.error(self.get_lang_message("invalid_json_response"))
123 |                     raise NetworkError(self.get_lang_message("invalid_json_response"))
124 |             
125 |             except socket.timeout:
126 |                 logging.warning(self.get_lang_message("connection_timed_out"))
127 |             except Exception as e:
128 |                 logging.error(
129 |                     self.get_lang_message(
130 |                         "connection_error",
131 |                         error=str(e)
132 |                     )
133 |                 )
134 |             
135 |             # Bei Misserfolg (und wenn noch Versuche übrig): warten, neu versuchen
136 |             if attempt < self.retries:
137 |                 logging.info(
138 |                     self.get_lang_message(
139 |                         "retrying_in_seconds",
140 |                         delay=self.delay
141 |                     )
142 |                 )
143 |                 time.sleep(self.delay)
144 |             
145 |             # Socket schließen (wenn noch offen), kein shutdown(SHUT_RDWR) verwenden
146 |             if client_socket is not None:
147 |                 try:
148 |                     client_socket.close()
149 |                 except:
150 |                     pass
151 |         
152 |         # Nach allen Versuchen fehlgeschlagen
153 |         logging.error(self.get_lang_message("all_retries_failed"))
154 |         raise NetworkError(self.get_lang_message("all_retries_failed"))
155 | 
```

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

```php
  1 | <?php
  2 | /**
  3 |  * MCPListGroupsClient.php
  4 |  *
  5 |  * A PHP script acting as a List Groups Client. It connects to a server via TCP,
  6 |  * sends a request to list groups, and receives the server's response.
  7 |  *
  8 |  * Usage:
  9 |  * php MCPListGroupsClient.php --server-ip <IP> --server-port <Port> --token <Token>
 10 |  */
 11 | 
 12 | /**
 13 |  * Function to parse command line arguments
 14 |  *
 15 |  * @param array $args Command line arguments
 16 |  * @return array Associative array of parsed arguments
 17 |  */
 18 | function parseArguments($args) {
 19 |     $parsedArgs = [];
 20 |     $argc = count($args);
 21 |     for ($i = 1; $i < $argc; $i++) {
 22 |         switch ($args[$i]) {
 23 |             case '--server-ip':
 24 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 25 |                     $parsedArgs['serverIp'] = $args[++$i];
 26 |                 } else {
 27 |                     fwrite(STDERR, "Error: --server-ip expects a value.\n");
 28 |                     exit(1);
 29 |                 }
 30 |                 break;
 31 |             case '--server-port':
 32 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 33 |                     $parsedArgs['serverPort'] = intval($args[++$i]);
 34 |                 } else {
 35 |                     fwrite(STDERR, "Error: --server-port expects a value.\n");
 36 |                     exit(1);
 37 |                 }
 38 |                 break;
 39 |             case '--token':
 40 |                 if (isset($args[$i + 1]) && !startsWith($args[$i + 1], '--')) {
 41 |                     $parsedArgs['token'] = $args[++$i];
 42 |                 } else {
 43 |                     fwrite(STDERR, "Error: --token expects a value.\n");
 44 |                     exit(1);
 45 |                 }
 46 |                 break;
 47 |             default:
 48 |                 fwrite(STDERR, "⚠️ Warning: Unknown argument: {$args[$i]}\n");
 49 |         }
 50 |     }
 51 |     return $parsedArgs;
 52 | }
 53 | 
 54 | /**
 55 |  * Helper function to check if a string starts with a specific prefix
 56 |  *
 57 |  * @param string $string The string to check
 58 |  * @param string $prefix The prefix
 59 |  * @return bool True if the string starts with the prefix, otherwise False
 60 |  */
 61 | function startsWith($string, $prefix) {
 62 |     return substr($string, 0, strlen($prefix)) === $prefix;
 63 | }
 64 | 
 65 | /**
 66 |  * Function for interactively prompting a parameter (optional)
 67 |  *
 68 |  * @param string $prompt The prompt message
 69 |  * @return string User input
 70 |  */
 71 | function askQuestionPrompt($prompt) {
 72 |     if (preg_match('/^win/i', PHP_OS)) {
 73 |         $vbscript = sys_get_temp_dir() . 'prompt_input.vbs';
 74 |         file_put_contents($vbscript, 'wscript.echo(InputBox("' . addslashes($prompt) . '", "", ""))');
 75 |         $response = shell_exec("cscript //nologo " . escapeshellarg($vbscript));
 76 |         unlink($vbscript);
 77 |         return trim($response);
 78 |     } else {
 79 |         echo $prompt;
 80 |         $handle = fopen("php://stdin", "r");
 81 |         $response = trim(fgets($handle));
 82 |         fclose($handle);
 83 |         return $response;
 84 |     }
 85 | }
 86 | 
 87 | /**
 88 |  * Function to send a generic request over a TCP connection
 89 |  *
 90 |  * @param string $serverIp The server's IP address
 91 |  * @param int $serverPort The server's port
 92 |  * @param array $payload The payload to send as an associative array
 93 |  * @return array The response received from the server as an associative array
 94 |  * @throws Exception On connection errors or JSON parsing errors
 95 |  */
 96 | function sendRequest($serverIp, $serverPort, $payload) {
 97 |     $jsonPayload = json_encode($payload);
 98 |     if ($jsonPayload === false) {
 99 |         throw new Exception("Error while coding the JSON payload: " . json_last_error_msg());
100 |     }
101 | 
102 |     $errno = 0;
103 |     $errstr = '';
104 |     $timeoutDuration = 10; // Seconds
105 |     $client = @fsockopen($serverIp, $serverPort, $errno, $errstr, $timeoutDuration);
106 |     
107 |     if (!$client) {
108 |         throw new Exception("Connection error: $errstr ($errno)");
109 |     }
110 | 
111 |     echo "🔗 Connected to the server ({$serverIp}:{$serverPort}).\n";
112 |     echo "📤 Sending payload: $jsonPayload\n";
113 | 
114 |     fwrite($client, $jsonPayload);
115 | 
116 |     $responseData = '';
117 |     stream_set_timeout($client, $timeoutDuration);
118 | 
119 |     while (!feof($client)) {
120 |         $data = fread($client, 1024);
121 |         if ($data === false) {
122 |             throw new Exception("Error reading data from the server.");
123 |         }
124 |         if ($data === '') {
125 |             break; // No more data
126 |         }
127 |         echo "📥 Received data: $data\n";
128 |         $responseData .= $data;
129 | 
130 |         $parsedData = json_decode($responseData, true);
131 |         if ($parsedData !== null) {
132 |             echo "✅ JSON response successfully parsed.\n";
133 |             fclose($client);
134 |             return $parsedData;
135 |         }
136 | 
137 |         $info = stream_get_meta_data($client);
138 |         if ($info['timed_out']) {
139 |             throw new Exception("Timeout waiting for data from the server.");
140 |         }
141 |     }
142 | 
143 |     fclose($client);
144 |     throw new Exception("Connection to the server was closed before a complete response was received.");
145 | }
146 | 
147 | /**
148 |  * Main function of the script
149 |  */
150 | function main($argv) {
151 |     $parsedArgs = parseArguments($argv);
152 |     $serverIp = $parsedArgs['serverIp'] ?? null;
153 |     $serverPort = $parsedArgs['serverPort'] ?? null;
154 |     $token = $parsedArgs['token'] ?? null;
155 | 
156 |     if (!$serverIp) {
157 |         $serverIp = askQuestionPrompt('🔗 Please enter the server IP: ');
158 |     }
159 |     if (!$serverPort) {
160 |         $portInput = askQuestionPrompt('🔗 Please enter the server port: ');
161 |         $serverPort = intval($portInput);
162 |         if ($serverPort <= 0) {
163 |             fwrite(STDERR, "❌ ERROR: Invalid server port.\n");
164 |             exit(1);
165 |         }
166 |     }
167 |     if (!$token) {
168 |         $token = askQuestionPrompt('🔒 Please enter your authentication token: ');
169 |     }
170 | 
171 |     if (!$serverIp || !$serverPort || !$token) {
172 |         fwrite(STDERR, "❌ ERROR: Missing required parameters.\n");
173 |         fwrite(STDOUT, "Usage: php MCPListGroupsClient.php --server-ip <IP> --server-port <Port> --token <Token>\n");
174 |         exit(1);
175 |     }
176 | 
177 |     $payload = [
178 |         "command" => "list_groups",
179 |         "token" => $token
180 |     ];
181 | 
182 |     try {
183 |         echo "📄 Retrieving groups...\n";
184 |         $response = sendRequest($serverIp, $serverPort, $payload);
185 |         echo "✔️ Response:\n";
186 |         echo json_encode($response, JSON_PRETTY_PRINT) . "\n";
187 |     } catch (Exception $e) {
188 |         fwrite(STDERR, "❌ ERROR: " . $e->getMessage() . "\n");
189 |     }
190 | }
191 | 
192 | if (version_compare(PHP_VERSION, '7.1.0') < 0) {
193 |     fwrite(STDERR, "❌ ERROR: This script requires PHP version 7.1 or higher.\n");
194 |     exit(1);
195 | }
196 | 
197 | main($argv);
198 | ?>
199 | 
```

--------------------------------------------------------------------------------
/clients/C# .Net/3.3 mcp_edit_source/Program.cs:
--------------------------------------------------------------------------------

```csharp
  1 | using System;
  2 | using System.Collections.Generic;
  3 | using System.Linq;
  4 | using System.Net.Sockets;
  5 | using System.Text;
  6 | using Newtonsoft.Json;
  7 | 
  8 | namespace MCPEditSourceClient
  9 | {
 10 |     class Program
 11 |     {
 12 |         static void Main(string[] args)
 13 |         {
 14 |             // Parameterprüfung (mind. 8 Elemente, weil 4 Pflichtargumente: 
 15 |             // --server-ip, --server-port, --token, --source-id)
 16 |             // plus optionale Argumente (--title, --content, --groups).
 17 |             if (args.Length < 8)
 18 |             {
 19 |                 Console.WriteLine("Usage:");
 20 |                 Console.WriteLine("  --server-ip <IP> --server-port <PORT> --token <TOKEN> --source-id <SOURCE_ID>");
 21 |                 Console.WriteLine("  [--title <TITLE>] [--content <CONTENT>] [--groups <LIST_OF_GROUPS>]");
 22 |                 return;
 23 |             }
 24 | 
 25 |             // Argumente auslesen
 26 |             string serverIp  = GetArgument(args, "--server-ip");
 27 |             string portStr   = GetArgument(args, "--server-port");
 28 |             string token     = GetArgument(args, "--token");
 29 |             string sourceId  = GetArgument(args, "--source-id");
 30 |             string title     = GetArgument(args, "--title");
 31 |             string content   = GetArgument(args, "--content");
 32 |             List<string> groups = GetListArgument(args, "--groups");
 33 | 
 34 |             if (serverIp == null || portStr == null || token == null || sourceId == null)
 35 |             {
 36 |                 Console.WriteLine("Fehler: Mindestens eines der Pflichtargumente wurde nicht angegeben.");
 37 |                 return;
 38 |             }
 39 | 
 40 |             if (!int.TryParse(portStr, out int serverPort))
 41 |             {
 42 |                 Console.WriteLine("Fehler: --server-port muss eine ganzzahlige Portangabe sein.");
 43 |                 return;
 44 |             }
 45 | 
 46 |             // Anfrage an den Server senden
 47 |             string response = SendEditSourceRequest(
 48 |                 serverIp,
 49 |                 serverPort,
 50 |                 token,
 51 |                 sourceId,
 52 |                 title,
 53 |                 content,
 54 |                 groups
 55 |             );
 56 | 
 57 |             Console.WriteLine("Response from server:");
 58 |             Console.WriteLine(response);
 59 |         }
 60 | 
 61 |         /// <summary>
 62 |         /// Sendet die Edit-Source-Anfrage an den MCP-Server.
 63 |         /// </summary>
 64 |         /// <param name="serverIp">IP-Adresse des MCP-Servers</param>
 65 |         /// <param name="serverPort">Port des MCP-Servers</param>
 66 |         /// <param name="token">Authentifizierungstoken</param>
 67 |         /// <param name="sourceId">ID der zu bearbeitenden Quelle</param>
 68 |         /// <param name="title">Neuer Titel der Quelle (optional)</param>
 69 |         /// <param name="content">Neuer Inhalt (Markdown) (optional)</param>
 70 |         /// <param name="groups">Liste der neuen Gruppen (optional)</param>
 71 |         /// <returns>String-Antwort des Servers oder Fehlermeldung</returns>
 72 |         static string SendEditSourceRequest(
 73 |             string serverIp,
 74 |             int serverPort,
 75 |             string token,
 76 |             string sourceId,
 77 |             string title = null,
 78 |             string content = null,
 79 |             List<string> groups = null)
 80 |         {
 81 |             // Payload zusammenbauen
 82 |             var arguments = new Dictionary<string, object>
 83 |             {
 84 |                 { "sourceId", sourceId }
 85 |             };
 86 | 
 87 |             // Nur hinzufügen, wenn nicht null
 88 |             if (!string.IsNullOrWhiteSpace(title))
 89 |                 arguments["title"] = title;
 90 | 
 91 |             if (!string.IsNullOrWhiteSpace(content))
 92 |                 arguments["content"] = content;
 93 | 
 94 |             // Falls keine Gruppen übergeben wurden, leere Liste setzen
 95 |             arguments["groups"] = groups ?? new List<string>();
 96 | 
 97 |             // Payload-Objekt erstellen
 98 |             var payload = new
 99 |             {
100 |                 command = "edit_source",
101 |                 token = token,
102 |                 arguments
103 |             };
104 | 
105 |             // JSON serialisieren
106 |             string payloadJson = JsonConvert.SerializeObject(payload);
107 | 
108 |             // Per TCP an den Server senden
109 |             try
110 |             {
111 |                 using (var client = new TcpClient(serverIp, serverPort))
112 |                 using (NetworkStream stream = client.GetStream())
113 |                 {
114 |                     // Senden
115 |                     byte[] data = Encoding.UTF8.GetBytes(payloadJson);
116 |                     stream.Write(data, 0, data.Length);
117 | 
118 |                     // Antwort empfangen
119 |                     byte[] buffer = new byte[4096];
120 |                     int bytesRead;
121 |                     StringBuilder responseBuilder = new StringBuilder();
122 | 
123 |                     do
124 |                     {
125 |                         bytesRead = stream.Read(buffer, 0, buffer.Length);
126 |                         responseBuilder.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead));
127 |                     } while (bytesRead == buffer.Length);
128 | 
129 |                     return responseBuilder.ToString();
130 |                 }
131 |             }
132 |             catch (Exception e)
133 |             {
134 |                 return $"Error: {e.Message}";
135 |             }
136 |         }
137 | 
138 |         /// <summary>
139 |         /// Liest den Wert eines bestimmten Keys aus args aus (z.B. --server-ip 127.0.0.1).
140 |         /// </summary>
141 |         /// <param name="args">Alle Argumente</param>
142 |         /// <param name="key">Gesuchter Key (z.B. "--server-ip")</param>
143 |         /// <returns>Wert des Keys oder null</returns>
144 |         static string GetArgument(string[] args, string key)
145 |         {
146 |             int index = Array.IndexOf(args, key);
147 |             return index >= 0 && index < args.Length - 1 ? args[index + 1] : null;
148 |         }
149 | 
150 |         /// <summary>
151 |         /// Liest eine Liste an Werten aus, die auf den key folgen (z.B. --groups G1 G2 --irgendeinAndererKey ...).
152 |         /// </summary>
153 |         /// <param name="args">Alle Argumente</param>
154 |         /// <param name="key">Gesuchter Key (z.B. "--groups")</param>
155 |         /// <returns>Liste gefundener Werte oder eine leere Liste</returns>
156 |         static List<string> GetListArgument(string[] args, string key)
157 |         {
158 |             var result = new List<string>();
159 |             int index = Array.IndexOf(args, key);
160 |             if (index >= 0)
161 |             {
162 |                 for (int i = index + 1; i < args.Length && !args[i].StartsWith("--"); i++)
163 |                 {
164 |                     result.Add(args[i]);
165 |                 }
166 |             }
167 |             return result;
168 |         }
169 |     }
170 | }
171 | 
```
Page 11/20FirstPrevNextLast