This is page 10 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++/3.0 mcp_create_source/MCPCreateSourceClient.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") // Winsock-Bibliothek verlinken 12 | 13 | // Funktion zum Argument-Parsing 14 | std::map<std::string, std::string> parseArguments(int argc, char* argv[], std::vector<std::string>& groups) { 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 | if (key == "--groups") { 20 | while (++i < argc && argv[i][0] != '-') { 21 | groups.push_back(argv[i]); 22 | } 23 | --i; // Schritt zurücksetzen, um nicht zu überspringen 24 | } else { 25 | args[key] = argv[++i]; 26 | } 27 | } 28 | } 29 | return args; 30 | } 31 | 32 | // Funktion zum Senden der Anfrage 33 | std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) { 34 | Json::StreamWriterBuilder writer; 35 | std::string payloadJson = Json::writeString(writer, payload); 36 | 37 | // Winsock initialisieren 38 | WSADATA wsaData; 39 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { 40 | throw std::runtime_error("Failed to initialize Winsock."); 41 | } 42 | 43 | // Socket erstellen 44 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 45 | if (sock == INVALID_SOCKET) { 46 | WSACleanup(); 47 | throw std::runtime_error("Failed to create socket."); 48 | } 49 | 50 | // Server-Adresse konfigurieren 51 | sockaddr_in serverAddr; 52 | serverAddr.sin_family = AF_INET; 53 | serverAddr.sin_port = htons(serverPort); 54 | if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) { 55 | closesocket(sock); 56 | WSACleanup(); 57 | throw std::runtime_error("Invalid server IP address."); 58 | } 59 | 60 | // Verbindung herstellen 61 | if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { 62 | closesocket(sock); 63 | WSACleanup(); 64 | throw std::runtime_error("Connection failed."); 65 | } 66 | 67 | // Daten senden 68 | if (send(sock, payloadJson.c_str(), payloadJson.size(), 0) < 0) { 69 | closesocket(sock); 70 | WSACleanup(); 71 | throw std::runtime_error("Failed to send data."); 72 | } 73 | 74 | // Antwort empfangen 75 | char buffer[4096]; 76 | int bytesRead; 77 | std::ostringstream response; 78 | 79 | do { 80 | bytesRead = recv(sock, buffer, sizeof(buffer) - 1, 0); 81 | if (bytesRead > 0) { 82 | buffer[bytesRead] = '\0'; // Null-terminieren 83 | response << buffer; 84 | } 85 | } while (bytesRead == sizeof(buffer) - 1); 86 | 87 | // Socket schließen 88 | closesocket(sock); 89 | WSACleanup(); 90 | 91 | return response.str(); 92 | } 93 | 94 | int main(int argc, char* argv[]) { 95 | try { 96 | std::vector<std::string> groups; 97 | auto args = parseArguments(argc, argv, groups); 98 | 99 | // Argumente extrahieren 100 | std::string serverIp = args["--server-ip"]; 101 | int serverPort = std::stoi(args["--server-port"]); 102 | std::string token = args["--token"]; 103 | std::string name = args["--name"]; 104 | std::string content = args["--content"]; 105 | 106 | // Überprüfen, ob alle erforderlichen Parameter angegeben sind 107 | if (serverIp.empty() || serverPort == 0 || token.empty() || name.empty() || content.empty()) { 108 | std::cerr << "Usage: MCPCreateSourceClient --server-ip <IP> --server-port <PORT> --token <TOKEN> --name <NAME> --content <CONTENT> [--groups <GROUP1 GROUP2 ...>]\n"; 109 | return 1; 110 | } 111 | 112 | std::cout << "📤 Sending request to create a new source...\n"; 113 | 114 | // JSON-Payload erstellen 115 | Json::Value payload; 116 | payload["command"] = "create_source"; 117 | payload["token"] = token; 118 | payload["arguments"]["name"] = name; 119 | payload["arguments"]["content"] = content; 120 | 121 | Json::Value groupsJson(Json::arrayValue); 122 | for (const auto& group : groups) { 123 | groupsJson.append(group); 124 | } 125 | payload["arguments"]["groups"] = groupsJson; 126 | 127 | // Anfrage senden und Antwort erhalten 128 | std::string response = sendRequest(serverIp, serverPort, payload); 129 | 130 | std::cout << "✔️ Response from server:\n" << response << "\n"; 131 | } catch (const std::exception& e) { 132 | std::cerr << "❌ ERROR: " << e.what() << "\n"; 133 | return 1; 134 | } 135 | 136 | return 0; 137 | } 138 | ``` -------------------------------------------------------------------------------- /clients/Python/2.0 mcp_chat/MCPChatClient.py: -------------------------------------------------------------------------------- ```python 1 | import socket 2 | import ssl 3 | import json 4 | import argparse 5 | import sys 6 | sys.stdout.reconfigure(encoding='utf-8') 7 | sys.stdin.reconfigure(encoding='utf-8') 8 | 9 | 10 | def send_mcp_request(server_ip, server_port, token, question, use_public, groups=None, language="de", use_ssl=True, accept_self_signed=False): 11 | """ 12 | Sends a question to an MCP server and retrieves the response. 13 | 14 | :param server_ip: IP address of the MCP server 15 | :param server_port: Port number of the MCP server 16 | :param token: Authentication token for the MCP server 17 | :param question: The question to send 18 | :param use_public: Whether to use the public knowledge base 19 | :param groups: List of groups for retrieval-augmented generation 20 | :param language: Language code for the request 21 | :param use_ssl: Whether to use SSL/TLS for the connection 22 | :param accept_self_signed: Whether to accept self-signed certificates 23 | :return: Response from the server 24 | """ 25 | # Prepare the request payload 26 | payload = { 27 | "command": "chat", 28 | "token": token, 29 | "arguments": { 30 | "question": question, 31 | "usePublic": use_public, 32 | "groups": groups or [], 33 | "language": language 34 | } 35 | } 36 | 37 | # Convert the payload to a JSON string 38 | payload_json = json.dumps(payload) 39 | 40 | # Initialize socket variables 41 | raw_socket = None 42 | client_socket = None 43 | 44 | try: 45 | # Create a socket object 46 | raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 47 | raw_socket.settimeout(10) 48 | 49 | # Establish SSL/TLS connection if required 50 | if use_ssl: 51 | context = ssl.create_default_context() 52 | if accept_self_signed: 53 | context.check_hostname = False 54 | context.verify_mode = ssl.CERT_NONE 55 | client_socket = context.wrap_socket(raw_socket, server_hostname=server_ip) 56 | else: 57 | client_socket = raw_socket 58 | 59 | # Connect to the server 60 | client_socket.connect((server_ip, server_port)) 61 | 62 | # Send the request 63 | client_socket.sendall(payload_json.encode('utf-8')) 64 | 65 | # Receive the response 66 | response = b"" 67 | while True: 68 | part = client_socket.recv(4096) 69 | if not part: 70 | break 71 | response += part 72 | 73 | # Decode the response 74 | return json.loads(response.decode('utf-8')) 75 | 76 | except ssl.SSLError: 77 | return {"status": "error", "message": "Connection failed: Server and/or Client may require TLS encryption. Please enable SSL/TLS."} 78 | except Exception as e: 79 | return {"status": "error", "message": str(e)} 80 | 81 | finally: 82 | if client_socket is not None: 83 | try: 84 | client_socket.shutdown(socket.SHUT_RDWR) 85 | except: 86 | pass 87 | client_socket.close() 88 | 89 | if __name__ == "__main__": 90 | parser = argparse.ArgumentParser(description="Send a question to the MCP server and retrieve the response.") 91 | parser.add_argument("--server-ip", required=True, help="IP address of the MCP server") 92 | parser.add_argument("--server-port", required=True, type=int, help="Port number of the MCP server") 93 | parser.add_argument("--token", required=True, help="Authentication token") 94 | parser.add_argument("--question", required=True, help="The question to ask the MCP server") 95 | parser.add_argument("--use-public", action="store_true", help="Use the public knowledge base") 96 | parser.add_argument("--groups", nargs="*", help="List of groups for retrieval-augmented generation", default=[]) 97 | parser.add_argument("--language", default="de", help="Language code for the request (default: 'de')") 98 | parser.add_argument("--use-ssl", action="store_true", help="Connect using SSL/TLS") 99 | parser.add_argument("--accept-self-signed", action="store_true", help="Accept self-signed certificates (disable certificate verification)") 100 | 101 | args = parser.parse_args() 102 | 103 | # Send the question to the MCP server 104 | response = send_mcp_request( 105 | server_ip=args.server_ip, 106 | server_port=args.server_port, 107 | token=args.token, 108 | question=args.question, 109 | use_public=args.use_public, 110 | groups=args.groups, 111 | language=args.language, 112 | use_ssl=args.use_ssl, 113 | accept_self_signed=args.accept_self_signed 114 | ) 115 | 116 | print("Response from server:", json.dumps(response, indent=2, ensure_ascii=False)) 117 | ``` -------------------------------------------------------------------------------- /clients/C# .Net/5.1 mcp_edit_user/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 MCPEditUserClient 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | if (args.Length < 4) 15 | { 16 | Console.WriteLine("Usage: --server-ip <IP> --server-port <PORT> --token <TOKEN> --user-id <USER_ID> [optional parameters]"); 17 | return; 18 | } 19 | 20 | string serverIp = GetArgument(args, "--server-ip"); 21 | int serverPort = int.Parse(GetArgument(args, "--server-port")); 22 | string token = GetArgument(args, "--token"); 23 | string userId = GetArgument(args, "--user-id"); 24 | string name = GetArgument(args, "--name"); 25 | string email = GetArgument(args, "--email"); 26 | string password = GetArgument(args, "--password"); 27 | string language = GetArgument(args, "--language"); 28 | string timezone = GetArgument(args, "--timezone"); 29 | List<string> roles = GetListArgument(args, "--roles"); 30 | List<string> groups = GetListArgument(args, "--groups"); 31 | bool usePublic = Array.Exists(args, arg => arg == "--usePublic"); 32 | bool activateFtp = Array.Exists(args, arg => arg == "--activateFtp"); 33 | string ftpPassword = GetArgument(args, "--ftpPassword"); 34 | 35 | var arguments = new Dictionary<string, object> 36 | { 37 | { "userId", userId }, 38 | { "name", name }, 39 | { "email", email }, 40 | { "password", password }, 41 | { "language", language }, 42 | { "timezone", timezone }, 43 | { "roles", roles }, 44 | { "groups", groups }, 45 | { "usePublic", usePublic }, 46 | { "activateFtp", activateFtp }, 47 | { "ftpPassword", ftpPassword } 48 | }; 49 | 50 | // Remove null or empty values from arguments 51 | arguments = arguments.Where(kv => kv.Value != null && !(kv.Value is string str && string.IsNullOrWhiteSpace(str))).ToDictionary(kv => kv.Key, kv => kv.Value); 52 | 53 | var payload = new 54 | { 55 | command = "edit_user", 56 | token = token, 57 | arguments = arguments 58 | }; 59 | 60 | Console.WriteLine("📤 Sending edit user request..."); 61 | string response = SendRequest(serverIp, serverPort, payload); 62 | Console.WriteLine("✔️ Response from server:"); 63 | Console.WriteLine(response); 64 | } 65 | 66 | static string GetArgument(string[] args, string key) 67 | { 68 | int index = Array.IndexOf(args, key); 69 | return index >= 0 && index < args.Length - 1 ? args[index + 1] : null; 70 | } 71 | 72 | static List<string> GetListArgument(string[] args, string key) 73 | { 74 | int index = Array.IndexOf(args, key); 75 | List<string> values = new List<string>(); 76 | if (index >= 0) 77 | { 78 | for (int i = index + 1; i < args.Length && !args[i].StartsWith("--"); i++) 79 | { 80 | values.Add(args[i]); 81 | } 82 | } 83 | return values; 84 | } 85 | 86 | static string SendRequest(string serverIp, int serverPort, object payload) 87 | { 88 | string payloadJson = JsonConvert.SerializeObject(payload); 89 | 90 | try 91 | { 92 | using (TcpClient client = new TcpClient(serverIp, serverPort)) 93 | { 94 | NetworkStream stream = client.GetStream(); 95 | 96 | // Send payload 97 | byte[] data = Encoding.UTF8.GetBytes(payloadJson); 98 | stream.Write(data, 0, data.Length); 99 | 100 | // Receive response 101 | byte[] buffer = new byte[4096]; 102 | int bytesRead; 103 | StringBuilder response = new StringBuilder(); 104 | 105 | do 106 | { 107 | bytesRead = stream.Read(buffer, 0, buffer.Length); 108 | response.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead)); 109 | } while (bytesRead == buffer.Length); 110 | 111 | return response.ToString(); 112 | } 113 | } 114 | catch (Exception e) 115 | { 116 | return $"Error: {e.Message}"; 117 | } 118 | } 119 | } 120 | } 121 | ``` -------------------------------------------------------------------------------- /clients/C# .Net/Code Archiv/mcp_edit_user.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 MCPEditUserClient 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | if (args.Length < 4) 15 | { 16 | Console.WriteLine("Usage: --server-ip <IP> --server-port <PORT> --token <TOKEN> --user-id <USER_ID> [optional parameters]"); 17 | return; 18 | } 19 | 20 | string serverIp = GetArgument(args, "--server-ip"); 21 | int serverPort = int.Parse(GetArgument(args, "--server-port")); 22 | string token = GetArgument(args, "--token"); 23 | string userId = GetArgument(args, "--user-id"); 24 | string name = GetArgument(args, "--name"); 25 | string email = GetArgument(args, "--email"); 26 | string password = GetArgument(args, "--password"); 27 | string language = GetArgument(args, "--language"); 28 | string timezone = GetArgument(args, "--timezone"); 29 | List<string> roles = GetListArgument(args, "--roles"); 30 | List<string> groups = GetListArgument(args, "--groups"); 31 | bool usePublic = Array.Exists(args, arg => arg == "--usePublic"); 32 | bool activateFtp = Array.Exists(args, arg => arg == "--activateFtp"); 33 | string ftpPassword = GetArgument(args, "--ftpPassword"); 34 | 35 | var arguments = new Dictionary<string, object> 36 | { 37 | { "userId", userId }, 38 | { "name", name }, 39 | { "email", email }, 40 | { "password", password }, 41 | { "language", language }, 42 | { "timezone", timezone }, 43 | { "roles", roles }, 44 | { "groups", groups }, 45 | { "usePublic", usePublic }, 46 | { "activateFtp", activateFtp }, 47 | { "ftpPassword", ftpPassword } 48 | }; 49 | 50 | // Remove null or empty values from arguments 51 | arguments = arguments.Where(kv => kv.Value != null && !(kv.Value is string str && string.IsNullOrWhiteSpace(str))).ToDictionary(kv => kv.Key, kv => kv.Value); 52 | 53 | var payload = new 54 | { 55 | command = "edit_user", 56 | token = token, 57 | arguments = arguments 58 | }; 59 | 60 | Console.WriteLine("📤 Sending edit user request..."); 61 | string response = SendRequest(serverIp, serverPort, payload); 62 | Console.WriteLine("✔️ Response from server:"); 63 | Console.WriteLine(response); 64 | } 65 | 66 | static string GetArgument(string[] args, string key) 67 | { 68 | int index = Array.IndexOf(args, key); 69 | return index >= 0 && index < args.Length - 1 ? args[index + 1] : null; 70 | } 71 | 72 | static List<string> GetListArgument(string[] args, string key) 73 | { 74 | int index = Array.IndexOf(args, key); 75 | List<string> values = new List<string>(); 76 | if (index >= 0) 77 | { 78 | for (int i = index + 1; i < args.Length && !args[i].StartsWith("--"); i++) 79 | { 80 | values.Add(args[i]); 81 | } 82 | } 83 | return values; 84 | } 85 | 86 | static string SendRequest(string serverIp, int serverPort, object payload) 87 | { 88 | string payloadJson = JsonConvert.SerializeObject(payload); 89 | 90 | try 91 | { 92 | using (TcpClient client = new TcpClient(serverIp, serverPort)) 93 | { 94 | NetworkStream stream = client.GetStream(); 95 | 96 | // Send payload 97 | byte[] data = Encoding.UTF8.GetBytes(payloadJson); 98 | stream.Write(data, 0, data.Length); 99 | 100 | // Receive response 101 | byte[] buffer = new byte[4096]; 102 | int bytesRead; 103 | StringBuilder response = new StringBuilder(); 104 | 105 | do 106 | { 107 | bytesRead = stream.Read(buffer, 0, buffer.Length); 108 | response.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead)); 109 | } while (bytesRead == buffer.Length); 110 | 111 | return response.ToString(); 112 | } 113 | } 114 | catch (Exception e) 115 | { 116 | return $"Error: {e.Message}"; 117 | } 118 | } 119 | } 120 | } 121 | ``` -------------------------------------------------------------------------------- /clients/JavaScript/3.4 mcp_delete_source/MCPDeleteSourceClient.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 | default: 23 | console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`); 24 | } 25 | } 26 | return parsedArgs; 27 | } 28 | 29 | // Funktion zum interaktiven Abfragen eines Parameters (optional) 30 | function askQuestion(query) { 31 | const rl = readline.createInterface({ 32 | input: process.stdin, 33 | output: process.stdout, 34 | terminal: true 35 | }); 36 | 37 | return new Promise((resolve) => { 38 | rl.question(query, (answer) => { 39 | rl.close(); 40 | resolve(answer); 41 | }); 42 | }); 43 | } 44 | 45 | // Funktion zum Senden einer Delete-Source-Anfrage über eine TCP-Verbindung 46 | function sendDeleteSourceRequest(serverIp, serverPort, payload) { 47 | return new Promise((resolve, reject) => { 48 | const client = new net.Socket(); 49 | let responseData = ''; 50 | const TIMEOUT_DURATION = 10000; // 10 Sekunden 51 | 52 | // Setze einen Timeout 53 | const timeout = setTimeout(() => { 54 | client.destroy(); // Zerstöre die Verbindung 55 | reject(new Error('Verbindungs-Timeout: Der Server hat nicht rechtzeitig geantwortet.')); 56 | }, TIMEOUT_DURATION); 57 | 58 | client.connect(serverPort, serverIp, () => { 59 | console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`); 60 | const payloadString = JSON.stringify(payload); 61 | console.log(`📤 Sende Payload: ${payloadString}`); 62 | client.write(payloadString); 63 | }); 64 | 65 | client.on('data', (data) => { 66 | console.log(`📥 Empfangene Daten: ${data}`); 67 | responseData += data.toString(); 68 | try { 69 | const parsedData = JSON.parse(responseData); 70 | console.log('✅ JSON-Antwort erfolgreich geparst.'); 71 | clearTimeout(timeout); // Entferne den Timeout 72 | resolve(parsedData); 73 | client.destroy(); // Verbindung schließen 74 | } catch (err) { 75 | console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.'); 76 | // Antwort noch nicht vollständig, weiter empfangen 77 | } 78 | }); 79 | 80 | client.on('close', () => { 81 | console.log('🔒 Verbindung zum Server geschlossen.'); 82 | clearTimeout(timeout); // Entferne den Timeout 83 | }); 84 | 85 | client.on('error', (err) => { 86 | console.error('❌ Verbindungsfehler:', err.message); 87 | clearTimeout(timeout); // Entferne den Timeout 88 | reject(err); 89 | }); 90 | }); 91 | } 92 | 93 | // Hauptfunktion 94 | async function main() { 95 | const args = argv; 96 | const parsedArgs = parseArguments(args); 97 | let { serverIp, serverPort, token, sourceId } = parsedArgs; 98 | 99 | // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen 100 | if (!serverIp) { 101 | serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: '); 102 | } 103 | if (!serverPort) { 104 | const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: '); 105 | serverPort = parseInt(portInput, 10); 106 | } 107 | if (!token) { 108 | token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: '); 109 | } 110 | if (!sourceId) { 111 | sourceId = await askQuestion('📁 Bitte gib die Source-ID ein: '); 112 | } 113 | 114 | const payload = { 115 | command: "delete_source", 116 | token: token, 117 | arguments: { 118 | sourceId: sourceId 119 | } 120 | }; 121 | 122 | try { 123 | console.log('🗑️ Sende Delete-Source-Anfrage...'); 124 | const response = await sendDeleteSourceRequest(serverIp, serverPort, payload); 125 | console.log('✅ Server Response:'); 126 | console.log(JSON.stringify(response, null, 2)); 127 | } catch (err) { 128 | console.error('❌ ERROR:', err.message); 129 | } 130 | } 131 | 132 | main(); 133 | ``` -------------------------------------------------------------------------------- /agents/OpenAI_Compatible_API_Agent/Python/vllmproxy.py: -------------------------------------------------------------------------------- ```python 1 | import argparse 2 | import asyncio 3 | import json 4 | import time 5 | import httpx 6 | from openai import OpenAI 7 | from openai.types.chat import ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam, \ 8 | ChatCompletionSystemMessageParam, ChatCompletionToolParam 9 | from starlette.responses import StreamingResponse 10 | 11 | from fastapi import FastAPI, Request, HTTPException 12 | from threading import local 13 | 14 | from agents.OpenAI_Compatible_API_Agent.Python.open_ai_helper import ChatCompletionRequest, models, Message, num_tokens, \ 15 | CompletionRequest 16 | import uvicorn 17 | 18 | 19 | app = FastAPI(title="OpenAI-compatible API for PrivateGPT") 20 | request_context = local() 21 | 22 | 23 | @app.middleware("http") 24 | async def store_request_headers(request: Request, call_next): 25 | request_context.headers = dict(request.headers) 26 | response = await call_next(request) 27 | return response 28 | 29 | @app.post("/chat/completions") 30 | async def chat_completions(request: ChatCompletionRequest): 31 | parser = argparse.ArgumentParser(description="Provide an API key to connect to OpenAI-compatible API.") 32 | parser.add_argument("--api_key", required=True, help="API key for login") 33 | parser.add_argument("--base_url", required=True, help="The base url of the VLLM server") 34 | args = parser.parse_args() 35 | 36 | 37 | client = OpenAI( 38 | base_url=args.base_url, 39 | api_key=args.api_key, 40 | http_client=httpx.Client(verify=False) 41 | ) 42 | 43 | 44 | msgs = [] 45 | for message in request.messages: 46 | if message.role == "system": 47 | msgs.append(ChatCompletionSystemMessageParam(role="system", content=message.content)) 48 | elif message.role == "user": 49 | msgs.append(ChatCompletionUserMessageParam(role="user", content=message.content)) 50 | elif message.role == "assistant": 51 | msgs.append(ChatCompletionAssistantMessageParam(role="assistant", content=message.content)) 52 | 53 | 54 | 55 | tools = [] 56 | #tools_json = json.loads(json.dumps(request.tools)) 57 | #for tool in tools_json: 58 | # tools.append(json.loads(str(tool))) 59 | 60 | #if len(tools) == 0: 61 | # tools = None 62 | 63 | response = client.chat.completions.create( 64 | model="/models/mistral-nemo-12b", 65 | temperature=request.temperature, 66 | #top_p=float(request.top_p), 67 | stream=True, 68 | tools=tools or None, 69 | messages=msgs 70 | ) 71 | 72 | if request.stream: 73 | 74 | return StreamingResponse( 75 | _resp_async_generator_vllm(response, request), media_type="application/x-ndjson" 76 | ) 77 | 78 | else: 79 | return { 80 | "id": response.id, 81 | "object": "chat.completion", 82 | "created": time.time(), 83 | "model": request.model, 84 | "choices": [{"message": Message(role="assistant", content="Response", tool_calls=[])}], 85 | "citations": [], 86 | "usage": { 87 | "prompt_tokens": 10, 88 | "completion_tokens": 10, 89 | "total_tokens": 20 90 | } 91 | } 92 | 93 | async def _resp_async_generator_vllm(response, request): 94 | partial_message = "" 95 | user_input = "" 96 | for message in request.messages: 97 | user_input += json.dumps({'role': message.role, 'content': message.content}) 98 | 99 | i = 0 100 | for chunk in response: 101 | num_tokens_request, num_tokens_reply, num_tokens_overall = num_tokens(user_input, chunk.choices[0].delta.content) 102 | chunk = { 103 | "id": i, 104 | "object": "chat.completion.chunk", 105 | "created": time.time(), 106 | "model": request.model, 107 | "choices": [{"delta": {"content": chunk.choices[0].delta.content}}], 108 | "usage": { 109 | "prompt_tokens": num_tokens_request, 110 | "completion_tokens": num_tokens_reply, 111 | "total_tokens": num_tokens_overall 112 | } 113 | } 114 | i = i+1 115 | yield f"data: {json.dumps(chunk)}\n\n" 116 | await asyncio.sleep(0.05) 117 | yield "data: [DONE]\n\n" 118 | 119 | 120 | @app.get("/models") 121 | def return_models(): 122 | return { 123 | "object": "list", 124 | "data": models 125 | } 126 | 127 | 128 | @app.get('/models/{model_id}') 129 | async def get_model(model_id: str): 130 | filtered_entries = list(filter(lambda item: item["id"] == model_id, models)) 131 | entry = filtered_entries[0] if filtered_entries else None 132 | print(entry) 133 | if entry is None: 134 | raise HTTPException(status_code=404, detail="Model not found") 135 | return entry 136 | 137 | 138 | if __name__ == "__main__": 139 | api_ip = "0.0.0.0" 140 | api_port = 8003 141 | uvicorn.run(app, host=api_ip, port=int(api_port)) 142 | 143 | 144 | 145 | ``` -------------------------------------------------------------------------------- /clients/Python/5.1 mcp_edit_user/MCPEditUserClient.py: -------------------------------------------------------------------------------- ```python 1 | import socket 2 | import ssl 3 | import json 4 | import argparse 5 | import sys 6 | 7 | def send_edit_user_request(server_ip, server_port, token, name=None, email=None, password=None, language=None, 8 | timezone=None, roles=None, groups=None, use_public=False, activate_ftp=False, ftp_password=None, 9 | use_ssl=True, accept_self_signed=False): 10 | """ 11 | Sends a request to edit an existing user to the MCP server. 12 | """ 13 | payload = { 14 | "command": "edit_user", 15 | "token": token, 16 | "arguments": { 17 | "name": name, 18 | "email": email, 19 | "password": password, 20 | "language": language, 21 | "timezone": timezone, 22 | "roles": roles or [], 23 | "groups": groups or [], 24 | "usePublic": use_public, 25 | "activateFtp": activate_ftp, 26 | "ftpPassword": ftp_password 27 | } 28 | } 29 | 30 | # Remove keys with None values 31 | payload["arguments"] = {k: v for k, v in payload["arguments"].items() if v is not None} 32 | 33 | payload_json = json.dumps(payload) 34 | 35 | raw_socket = None 36 | client_socket = None 37 | 38 | try: 39 | raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 40 | raw_socket.settimeout(10) 41 | 42 | if use_ssl: 43 | context = ssl.create_default_context() 44 | if accept_self_signed: 45 | context.check_hostname = False 46 | context.verify_mode = ssl.CERT_NONE 47 | client_socket = context.wrap_socket(raw_socket, server_hostname=server_ip) 48 | else: 49 | client_socket = raw_socket 50 | 51 | client_socket.connect((server_ip, server_port)) 52 | client_socket.sendall(payload_json.encode('utf-8')) 53 | 54 | response = b"" 55 | while True: 56 | part = client_socket.recv(4096) 57 | if not part: 58 | break 59 | response += part 60 | 61 | return response.decode('utf-8') 62 | except ssl.SSLError: 63 | return "Error: Server and/or client may require TLS encryption. Please enable SSL/TLS." 64 | except Exception as e: 65 | return f"Error: {e}" 66 | 67 | finally: 68 | if client_socket is not None: 69 | try: 70 | client_socket.shutdown(socket.SHUT_RDWR) 71 | except: 72 | pass 73 | client_socket.close() 74 | 75 | if __name__ == "__main__": 76 | parser = argparse.ArgumentParser( 77 | description="Send a request to edit an existing user to the MCP server.", 78 | formatter_class=argparse.RawTextHelpFormatter 79 | ) 80 | parser.add_argument("--server-ip", required=True, help="IP address of the MCP server") 81 | parser.add_argument("--server-port", required=True, type=int, help="Port number of the MCP server") 82 | parser.add_argument("--token", required=True, help="Authentication token") 83 | parser.add_argument("--name", help="New name of the user") 84 | parser.add_argument("--email", help="New email of the user") 85 | parser.add_argument("--password", help="New password of the user") 86 | parser.add_argument("--language", help="Preferred language of the user") 87 | parser.add_argument("--timezone", help="Timezone of the user") 88 | parser.add_argument("--roles", nargs="*", help="List of roles to assign to the user") 89 | parser.add_argument("--groups", nargs="*", help="List of groups to assign to the user") 90 | parser.add_argument("--usePublic", action="store_true", help="Enable public knowledge base access") 91 | parser.add_argument("--activateFtp", action="store_true", help="Activate FTP access") 92 | parser.add_argument("--ftpPassword", help="Password for FTP access") 93 | parser.add_argument("--use-ssl", action="store_true", help="Connect using SSL/TLS") 94 | parser.add_argument("--accept-self-signed", action="store_true", help="Accept self-signed certificates (disable certificate verification)") 95 | 96 | if len(sys.argv) == 1: 97 | parser.print_help(sys.stderr) 98 | sys.exit(1) 99 | 100 | args = parser.parse_args() 101 | 102 | response = send_edit_user_request( 103 | args.server_ip, 104 | args.server_port, 105 | args.token, 106 | name=args.name, 107 | email=args.email, 108 | password=args.password, 109 | language=args.language, 110 | timezone=args.timezone, 111 | roles=args.roles, 112 | groups=args.groups, 113 | use_public=args.usePublic, 114 | activate_ftp=args.activateFtp, 115 | ftp_password=args.ftpPassword, 116 | use_ssl=args.use_ssl, 117 | accept_self_signed=args.accept_self_signed 118 | ) 119 | print("Response from server:", response) 120 | ``` -------------------------------------------------------------------------------- /clients/JavaScript/2.0 mcp_chat/MCPChatClient.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 '--question': 20 | parsedArgs.question = args[++i]; 21 | break; 22 | case '--use-public': 23 | parsedArgs.usePublic = true; 24 | break; 25 | case '--groups': 26 | // Sammle alle Gruppenargumente bis zum nächsten Flag oder Ende 27 | parsedArgs.groups = []; 28 | while (i + 1 < args.length && !args[i + 1].startsWith('--')) { 29 | parsedArgs.groups.push(args[++i]); 30 | } 31 | break; 32 | case '--language': 33 | parsedArgs.language = args[++i]; 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 Chat-Anfrage über eine TCP-Verbindung 59 | function sendChatRequest(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 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 | const { serverIp, serverPort, token, question, usePublic, groups, language } = parsedArgs; 101 | 102 | // Überprüfen, ob alle erforderlichen Parameter vorhanden sind 103 | if (!serverIp || !serverPort || !token || !question) { 104 | console.error('❌ ERROR: Fehlende erforderliche Parameter.'); 105 | console.log('Verwendung: node MCPChatClient.js --server-ip <IP> --server-port <Port> --token <Token> --question <Frage> [--use-public] [--groups <Gruppe1> <Gruppe2> ...] [--language <Sprache>]'); 106 | exit(1); 107 | } 108 | 109 | // Optional: Fallback für optionale Parameter 110 | const finalLanguage = language || 'de'; 111 | const finalGroups = groups || []; 112 | 113 | const payload = { 114 | command: "chat", 115 | token: token, 116 | arguments: { 117 | question: question, 118 | usePublic: usePublic || false, 119 | groups: finalGroups, 120 | language: finalLanguage 121 | } 122 | }; 123 | 124 | try { 125 | console.log('💬 Sende Chat-Anfrage...'); 126 | const response = await sendChatRequest(serverIp, serverPort, payload); 127 | console.log('✅ Server Response:'); 128 | console.log(JSON.stringify(response, null, 2)); 129 | } catch (err) { 130 | console.error('❌ ERROR:', err.message); 131 | } 132 | } 133 | 134 | main(); 135 | ``` -------------------------------------------------------------------------------- /src/services/pgpt-service.ts: -------------------------------------------------------------------------------- ```typescript 1 | import axios, { AxiosInstance } from 'axios'; 2 | import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; 3 | import { ChatArgs, SourceArgs, ListSourcesArgs, GetSourceArgs } from '../types/api.js'; 4 | 5 | export class PGPTService { 6 | private api: AxiosInstance; 7 | private token: string | null = null; 8 | 9 | constructor() { 10 | // Initialize axios instance with base configuration 11 | this.api = axios.create({ 12 | baseURL: process.env.PGPT_API_URL || 'http://localhost:3000', 13 | headers: { 14 | 'Accept': 'application/json', 15 | 'Content-Type': 'application/json', 16 | }, 17 | }); 18 | } 19 | 20 | private async ensureAuthenticated(): Promise<void> { 21 | if (!this.token) { 22 | const email = process.env.PGPT_EMAIL; 23 | const password = process.env.PGPT_PASSWORD; 24 | 25 | if (!email || !password) { 26 | throw new McpError( 27 | ErrorCode.InvalidRequest, 28 | 'Missing authentication credentials' 29 | ); 30 | } 31 | 32 | try { 33 | const response = await this.api.post('/api/v1/login', { 34 | email, 35 | password, 36 | }); 37 | this.token = response.data.data.token; 38 | this.api.defaults.headers.common['Authorization'] = `Bearer ${this.token}`; 39 | } catch (error) { 40 | throw new McpError( 41 | ErrorCode.InvalidRequest, 42 | 'Authentication failed' 43 | ); 44 | } 45 | } 46 | } 47 | 48 | async chat(args: ChatArgs) { 49 | await this.ensureAuthenticated(); 50 | 51 | try { 52 | const response = await this.api.post('/api/v1/chats', { 53 | language: args.language || 'en', 54 | question: args.question, 55 | usePublic: args.usePublic || false, 56 | groups: args.groups || [], 57 | }); 58 | 59 | return { 60 | content: [ 61 | { 62 | type: 'text', 63 | text: response.data.data.answer, 64 | }, 65 | ], 66 | }; 67 | } catch (error) { 68 | if (axios.isAxiosError(error)) { 69 | throw new McpError( 70 | ErrorCode.InternalError, 71 | `Chat failed: ${error.response?.data?.message || error.message}` 72 | ); 73 | } 74 | throw error; 75 | } 76 | } 77 | 78 | async createSource(args: SourceArgs) { 79 | await this.ensureAuthenticated(); 80 | 81 | try { 82 | const response = await this.api.post('/api/v1/sources', { 83 | name: args.name, 84 | content: args.content, 85 | groups: args.groups || [], 86 | }); 87 | 88 | return { 89 | content: [ 90 | { 91 | type: 'text', 92 | text: JSON.stringify(response.data.data, null, 2), 93 | }, 94 | ], 95 | }; 96 | } catch (error) { 97 | if (axios.isAxiosError(error)) { 98 | throw new McpError( 99 | ErrorCode.InternalError, 100 | `Source creation failed: ${error.response?.data?.message || error.message}` 101 | ); 102 | } 103 | throw error; 104 | } 105 | } 106 | 107 | async listGroups() { 108 | await this.ensureAuthenticated(); 109 | 110 | try { 111 | const response = await this.api.get('/api/v1/groups'); 112 | 113 | return { 114 | content: [ 115 | { 116 | type: 'text', 117 | text: JSON.stringify(response.data.data, null, 2), 118 | }, 119 | ], 120 | }; 121 | } catch (error) { 122 | if (axios.isAxiosError(error)) { 123 | throw new McpError( 124 | ErrorCode.InternalError, 125 | `Group listing failed: ${error.response?.data?.message || error.message}` 126 | ); 127 | } 128 | throw error; 129 | } 130 | } 131 | 132 | async listSources(args: ListSourcesArgs) { 133 | await this.ensureAuthenticated(); 134 | 135 | try { 136 | const response = await this.api.post('/api/v1/sources/groups', { 137 | groupName: args.groupName, 138 | }); 139 | 140 | return { 141 | content: [ 142 | { 143 | type: 'text', 144 | text: JSON.stringify(response.data.data, null, 2), 145 | }, 146 | ], 147 | }; 148 | } catch (error) { 149 | if (axios.isAxiosError(error)) { 150 | throw new McpError( 151 | ErrorCode.InternalError, 152 | `Source listing failed: ${error.response?.data?.message || error.message}` 153 | ); 154 | } 155 | throw error; 156 | } 157 | } 158 | 159 | async getSource(args: GetSourceArgs) { 160 | await this.ensureAuthenticated(); 161 | 162 | try { 163 | const response = await this.api.get(`/api/v1/sources/${args.sourceId}`); 164 | 165 | return { 166 | content: [ 167 | { 168 | type: 'text', 169 | text: JSON.stringify(response.data.data, null, 2), 170 | }, 171 | ], 172 | }; 173 | } catch (error) { 174 | if (axios.isAxiosError(error)) { 175 | throw new McpError( 176 | ErrorCode.InternalError, 177 | `Source retrieval failed: ${error.response?.data?.message || error.message}` 178 | ); 179 | } 180 | throw error; 181 | } 182 | } 183 | } 184 | ``` -------------------------------------------------------------------------------- /clients/C++/3.3 mcp_edit_source/MCPEditSourceClient.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") // Winsock-Bibliothek verlinken 12 | 13 | // Funktion zum Argument-Parsing 14 | std::map<std::string, std::string> parseArguments(int argc, char* argv[], std::vector<std::string>& groups) { 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 | if (key == "--groups") { 20 | while (++i < argc && argv[i][0] != '-') { 21 | groups.push_back(argv[i]); 22 | } 23 | --i; // Rückgängigmachen des letzten Schritts 24 | } else { 25 | args[key] = argv[++i]; 26 | } 27 | } 28 | } 29 | return args; 30 | } 31 | 32 | // Funktion zum Senden der Anfrage 33 | std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) { 34 | Json::StreamWriterBuilder writer; 35 | std::string payloadJson = Json::writeString(writer, payload); 36 | 37 | // Winsock initialisieren 38 | WSADATA wsaData; 39 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { 40 | throw std::runtime_error("Failed to initialize Winsock."); 41 | } 42 | 43 | // Socket erstellen 44 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 45 | if (sock == INVALID_SOCKET) { 46 | WSACleanup(); 47 | throw std::runtime_error("Failed to create socket."); 48 | } 49 | 50 | // Server-Adresse konfigurieren 51 | sockaddr_in serverAddr; 52 | serverAddr.sin_family = AF_INET; 53 | serverAddr.sin_port = htons(serverPort); 54 | if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) { 55 | closesocket(sock); 56 | WSACleanup(); 57 | throw std::runtime_error("Invalid server IP address."); 58 | } 59 | 60 | // Verbindung herstellen 61 | if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { 62 | closesocket(sock); 63 | WSACleanup(); 64 | throw std::runtime_error("Connection failed."); 65 | } 66 | 67 | // Daten senden 68 | if (send(sock, payloadJson.c_str(), payloadJson.size(), 0) < 0) { 69 | closesocket(sock); 70 | WSACleanup(); 71 | throw std::runtime_error("Failed to send data."); 72 | } 73 | 74 | // Antwort empfangen 75 | char buffer[4096]; 76 | int bytesRead; 77 | std::ostringstream response; 78 | 79 | do { 80 | bytesRead = recv(sock, buffer, sizeof(buffer) - 1, 0); 81 | if (bytesRead > 0) { 82 | buffer[bytesRead] = '\0'; // Null-terminieren 83 | response << buffer; 84 | } 85 | } while (bytesRead == sizeof(buffer) - 1); 86 | 87 | // Socket schließen 88 | closesocket(sock); 89 | WSACleanup(); 90 | 91 | return response.str(); 92 | } 93 | 94 | int main(int argc, char* argv[]) { 95 | try { 96 | std::vector<std::string> groups; 97 | auto args = parseArguments(argc, argv, groups); 98 | 99 | // Argumente extrahieren 100 | std::string serverIp = args["--server-ip"]; 101 | int serverPort = std::stoi(args["--server-port"]); 102 | std::string token = args["--token"]; 103 | std::string sourceId = args["--source-id"]; 104 | std::string title = args["--title"]; 105 | std::string content = args["--content"]; 106 | 107 | // Überprüfen, ob alle erforderlichen Parameter angegeben sind 108 | if (serverIp.empty() || serverPort == 0 || token.empty() || sourceId.empty()) { 109 | std::cerr << "Usage: MCPEditSourceClient --server-ip <IP> --server-port <PORT> --token <TOKEN> --source-id <SOURCE_ID> [--title <TITLE>] [--content <CONTENT>] [--groups <GROUP1 GROUP2 ...>]\n"; 110 | return 1; 111 | } 112 | 113 | std::cout << "📤 Sending request to edit the source...\n"; 114 | 115 | // JSON-Payload erstellen 116 | Json::Value payload; 117 | payload["command"] = "edit_source"; 118 | payload["token"] = token; 119 | 120 | Json::Value arguments; 121 | arguments["sourceId"] = sourceId; 122 | if (!title.empty()) { 123 | arguments["title"] = title; 124 | } 125 | if (!content.empty()) { 126 | arguments["content"] = content; 127 | } 128 | 129 | Json::Value groupsJson(Json::arrayValue); 130 | for (const auto& group : groups) { 131 | groupsJson.append(group); 132 | } 133 | arguments["groups"] = groupsJson; 134 | 135 | payload["arguments"] = arguments; 136 | 137 | // Anfrage senden und Antwort erhalten 138 | std::string response = sendRequest(serverIp, serverPort, payload); 139 | 140 | std::cout << "✔️ Response from server:\n" << response << "\n"; 141 | } catch (const std::exception& e) { 142 | std::cerr << "❌ ERROR: " << e.what() << "\n"; 143 | return 1; 144 | } 145 | 146 | return 0; 147 | } 148 | ``` -------------------------------------------------------------------------------- /clients/C++/2.0 mcp_chat/MCPChatClient.cpp: -------------------------------------------------------------------------------- ```cpp 1 | #include <iostream> 2 | #include <string> 3 | #include <vector> 4 | #include <map> 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") // Winsock-Bibliothek verlinken 12 | 13 | // Funktion zum Argument-Parsing 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 Senden der MCP-Anfrage 26 | std::string sendMCPRequest(const std::string& serverIp, int serverPort, const std::string& token, 27 | const std::string& question, bool usePublic, const std::vector<std::string>& groups, 28 | const std::string& language) { 29 | // JSON-Payload erstellen 30 | Json::Value payload; 31 | payload["command"] = "chat"; 32 | payload["token"] = token; 33 | payload["arguments"]["question"] = question; 34 | payload["arguments"]["usePublic"] = usePublic; 35 | payload["arguments"]["language"] = language; 36 | 37 | Json::Value groupsJson(Json::arrayValue); 38 | for (const auto& group : groups) { 39 | groupsJson.append(group); 40 | } 41 | payload["arguments"]["groups"] = groupsJson; 42 | 43 | Json::StreamWriterBuilder writer; 44 | std::string payloadJson = Json::writeString(writer, payload); 45 | 46 | // Winsock initialisieren 47 | WSADATA wsaData; 48 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { 49 | throw std::runtime_error("Failed to initialize Winsock."); 50 | } 51 | 52 | // Socket erstellen 53 | SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); 54 | if (sock == INVALID_SOCKET) { 55 | WSACleanup(); 56 | throw std::runtime_error("Failed to create socket."); 57 | } 58 | 59 | // Server-Adresse konfigurieren 60 | sockaddr_in serverAddr; 61 | serverAddr.sin_family = AF_INET; 62 | serverAddr.sin_port = htons(serverPort); 63 | if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) { 64 | closesocket(sock); 65 | WSACleanup(); 66 | throw std::runtime_error("Invalid server IP address."); 67 | } 68 | 69 | // Verbindung herstellen 70 | if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { 71 | closesocket(sock); 72 | WSACleanup(); 73 | throw std::runtime_error("Connection failed."); 74 | } 75 | 76 | // Daten senden 77 | if (send(sock, payloadJson.c_str(), payloadJson.size(), 0) < 0) { 78 | closesocket(sock); 79 | WSACleanup(); 80 | throw std::runtime_error("Failed to send data."); 81 | } 82 | 83 | // Antwort empfangen 84 | char buffer[4096]; 85 | int bytesRead; 86 | std::ostringstream response; 87 | 88 | do { 89 | bytesRead = recv(sock, buffer, sizeof(buffer) - 1, 0); 90 | if (bytesRead > 0) { 91 | buffer[bytesRead] = '\0'; // Null-terminieren 92 | response << buffer; 93 | } 94 | } while (bytesRead == sizeof(buffer) - 1); 95 | 96 | // Socket schließen 97 | closesocket(sock); 98 | WSACleanup(); 99 | 100 | return response.str(); 101 | } 102 | 103 | int main(int argc, char* argv[]) { 104 | try { 105 | auto args = parseArguments(argc, argv); 106 | 107 | // Argumente extrahieren 108 | std::string serverIp = args["--server-ip"]; 109 | int serverPort = std::stoi(args["--server-port"]); 110 | std::string token = args["--token"]; 111 | std::string question = args["--question"]; 112 | bool usePublic = args.find("--use-public") != args.end(); 113 | std::string language = args.count("--language") ? args["--language"] : "de"; 114 | 115 | // Gruppen extrahieren 116 | std::vector<std::string> groups; 117 | if (args.count("--groups")) { 118 | std::istringstream groupStream(args["--groups"]); 119 | std::string group; 120 | while (std::getline(groupStream, group, ',')) { 121 | groups.push_back(group); 122 | } 123 | } 124 | 125 | // Überprüfen, ob alle erforderlichen Parameter angegeben sind 126 | if (serverIp.empty() || serverPort == 0 || token.empty() || question.empty()) { 127 | std::cerr << "Usage: --server-ip <IP> --server-port <PORT> --token <TOKEN> --question <QUESTION> [--use-public] [--groups <GROUPS>] [--language <LANGUAGE>]\n"; 128 | return 1; 129 | } 130 | 131 | std::cout << "🔒 Sending MCP chat request...\n"; 132 | 133 | // MCP-Anfrage senden und Antwort erhalten 134 | std::string response = sendMCPRequest(serverIp, serverPort, token, question, usePublic, groups, language); 135 | 136 | std::cout << "Response from server:\n" << response << "\n"; 137 | } catch (const std::exception& e) { 138 | std::cerr << "❌ ERROR: " << e.what() << "\n"; 139 | return 1; 140 | } 141 | 142 | return 0; 143 | } 144 | ``` -------------------------------------------------------------------------------- /clients/JavaScript/3.0 mcp_create_source/MCPCreateSourceClient.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 '--name': 20 | parsedArgs.name = args[++i]; 21 | break; 22 | case '--content': 23 | parsedArgs.content = args[++i]; 24 | break; 25 | case '--groups': 26 | // Sammle alle Gruppenargumente bis zum nächsten Flag oder Ende 27 | parsedArgs.groups = []; 28 | while (i + 1 < args.length && !args[i + 1].startsWith('--')) { 29 | parsedArgs.groups.push(args[++i]); 30 | } 31 | break; 32 | default: 33 | console.warn(`⚠️ Unbekanntes Argument: ${args[i]}`); 34 | } 35 | } 36 | return parsedArgs; 37 | } 38 | 39 | // Funktion zum interaktiven Abfragen eines Parameters (optional) 40 | function askQuestion(query) { 41 | const rl = readline.createInterface({ 42 | input: process.stdin, 43 | output: process.stdout, 44 | terminal: true 45 | }); 46 | 47 | return new Promise((resolve) => { 48 | rl.question(query, (answer) => { 49 | rl.close(); 50 | resolve(answer); 51 | }); 52 | }); 53 | } 54 | 55 | // Funktion zum Senden einer Create-Source-Anfrage über eine TCP-Verbindung 56 | function sendCreateSourceRequest(serverIp, serverPort, payload) { 57 | return new Promise((resolve, reject) => { 58 | const client = new net.Socket(); 59 | let responseData = ''; 60 | 61 | client.connect(serverPort, serverIp, () => { 62 | console.log(`🔗 Verbindung zum Server (${serverIp}:${serverPort}) hergestellt.`); 63 | const payloadString = JSON.stringify(payload); 64 | console.log(`📤 Sende Payload: ${payloadString}`); 65 | client.write(payloadString); 66 | }); 67 | 68 | client.on('data', (data) => { 69 | console.log(`📥 Empfangene Daten: ${data}`); 70 | responseData += data.toString(); 71 | try { 72 | const parsedData = JSON.parse(responseData); 73 | console.log('✅ JSON-Antwort erfolgreich geparst.'); 74 | resolve(parsedData); 75 | client.destroy(); // Verbindung schließen 76 | } catch (err) { 77 | console.warn('⚠️ Antwort noch nicht vollständig oder ungültiges JSON. Weitere Daten werden erwartet.'); 78 | // Antwort noch nicht vollständig, weiter empfangen 79 | } 80 | }); 81 | 82 | client.on('close', () => { 83 | console.log('🔒 Verbindung zum Server geschlossen.'); 84 | }); 85 | 86 | client.on('error', (err) => { 87 | console.error('❌ Verbindungsfehler:', err.message); 88 | reject(err); 89 | }); 90 | }); 91 | } 92 | 93 | // Hauptfunktion 94 | async function main() { 95 | const args = argv; 96 | const parsedArgs = parseArguments(args); 97 | let { serverIp, serverPort, token, name, content, groups } = parsedArgs; 98 | 99 | // Überprüfen, ob alle erforderlichen Parameter vorhanden sind, sonst interaktiv abfragen 100 | if (!serverIp) { 101 | serverIp = await askQuestion('🔗 Bitte gib die Server-IP ein: '); 102 | } 103 | if (!serverPort) { 104 | const portInput = await askQuestion('🔗 Bitte gib den Server-Port ein: '); 105 | serverPort = parseInt(portInput, 10); 106 | } 107 | if (!token) { 108 | token = await askQuestion('🔒 Bitte gib dein Authentifizierungstoken ein: '); 109 | } 110 | if (!name) { 111 | name = await askQuestion('📛 Bitte gib den Namen der neuen Quelle ein: '); 112 | } 113 | if (!content) { 114 | content = await askQuestion('📝 Bitte gib den Inhalt der neuen Quelle (Markdown) ein: '); 115 | } 116 | if (!groups) { 117 | const groupsInput = await askQuestion('👥 Bitte gib die Gruppen an (getrennt durch Leerzeichen, optional): '); 118 | groups = groupsInput ? groupsInput.split(' ') : []; 119 | } 120 | 121 | const payload = { 122 | command: "create_source", 123 | token: token, 124 | arguments: { 125 | name: name, 126 | content: content, 127 | groups: groups 128 | } 129 | }; 130 | 131 | try { 132 | console.log('🛠️ Sende Create-Source-Anfrage...'); 133 | const response = await sendCreateSourceRequest(serverIp, serverPort, payload); 134 | console.log('✅ Server Response:'); 135 | console.log(JSON.stringify(response, null, 2)); 136 | } catch (err) { 137 | console.error('❌ ERROR:', err.message); 138 | } 139 | } 140 | 141 | main(); 142 | ``` -------------------------------------------------------------------------------- /clients/PHP/1.0 mcp_login/MCPLoginClient.php: -------------------------------------------------------------------------------- ```php 1 | <?php 2 | // Functions for parsing command line arguments 3 | function parseArguments($args) { 4 | $parsedArgs = []; 5 | $argc = count($args); 6 | for ($i = 1; $i < $argc; $i++) { 7 | switch ($args[$i]) { 8 | case '--server-ip': 9 | if (isset($args[$i + 1])) { 10 | $parsedArgs['serverIp'] = $args[++$i]; 11 | } else { 12 | fwrite(STDERR, "Error: --server-ip expects a value.\n"); 13 | exit(1); 14 | } 15 | break; 16 | case '--server-port': 17 | if (isset($args[$i + 1])) { 18 | $parsedArgs['serverPort'] = intval($args[++$i]); 19 | } else { 20 | fwrite(STDERR, "Error: --server-port expects a value.\n"); 21 | exit(1); 22 | } 23 | break; 24 | case '--email': 25 | if (isset($args[$i + 1])) { 26 | $parsedArgs['email'] = $args[++$i]; 27 | } else { 28 | fwrite(STDERR, "Error: --email expects a value.\n"); 29 | exit(1); 30 | } 31 | break; 32 | case '--password': 33 | if (isset($args[$i + 1])) { 34 | $parsedArgs['password'] = $args[++$i]; 35 | } else { 36 | fwrite(STDERR, "Error: --password expects a value.\n"); 37 | exit(1); 38 | } 39 | break; 40 | default: 41 | fwrite(STDERR, "Warning: Unknown argument: {$args[$i]}\n"); 42 | } 43 | } 44 | return $parsedArgs; 45 | } 46 | 47 | // Function for sending a request over a TCP connection 48 | function sendRequest($serverIp, $serverPort, $payload) { 49 | $jsonPayload = json_encode($payload); 50 | if ($jsonPayload === false) { 51 | throw new Exception("Error encoding JSON payload."); 52 | } 53 | 54 | $errno = 0; 55 | $errstr = ''; 56 | $timeout = 30; // seconds 57 | $client = fsockopen($serverIp, $serverPort, $errno, $errstr, $timeout); 58 | 59 | if (!$client) { 60 | throw new Exception("Connection error: $errstr ($errno)"); 61 | } 62 | 63 | echo "🔗 Connection to server established.\n"; 64 | 65 | fwrite($client, $jsonPayload); 66 | 67 | $responseData = ''; 68 | stream_set_timeout($client, $timeout); 69 | 70 | while (!feof($client)) { 71 | $data = fread($client, 1024); 72 | if ($data === false) { 73 | throw new Exception("Error reading data from server."); 74 | } 75 | $responseData .= $data; 76 | 77 | // Attempt to parse the received data as JSON 78 | $parsedData = json_decode($responseData, true); 79 | if ($parsedData !== null) { 80 | fclose($client); 81 | return $parsedData; 82 | } 83 | 84 | // Check if the stream timed out 85 | $info = stream_get_meta_data($client); 86 | if ($info['timed_out']) { 87 | throw new Exception("Timeout waiting for data from server."); 88 | } 89 | } 90 | 91 | fclose($client); 92 | throw new Exception("Connection to the server was closed before a complete response was received."); 93 | } 94 | 95 | // Function for interactively asking for a password (optional) 96 | function askPassword($prompt) { 97 | if (preg_match('/^win/i', PHP_OS)) { 98 | // Windows-specific password prompt 99 | $vbscript = sys_get_temp_dir() . 'prompt_password.vbs'; 100 | file_put_contents($vbscript, 'wscript.echo(InputBox("' . addslashes($prompt) . '", "", "password here"))'); 101 | $password = shell_exec("cscript //nologo " . escapeshellarg($vbscript)); 102 | unlink($vbscript); 103 | return trim($password); 104 | } else { 105 | // Unix/Linux password prompt 106 | echo $prompt; 107 | system('stty -echo'); 108 | $password = rtrim(fgets(STDIN), "\n"); 109 | system('stty echo'); 110 | echo "\n"; 111 | return $password; 112 | } 113 | } 114 | 115 | // Main function 116 | function main($argv) { 117 | $args = parseArguments($argv); 118 | $serverIp = $args['serverIp'] ?? null; 119 | $serverPort = $args['serverPort'] ?? null; 120 | $email = $args['email'] ?? null; 121 | $password = $args['password'] ?? null; 122 | 123 | // Check if all required parameters are present 124 | if (!$serverIp || !$serverPort || !$email || !$password) { 125 | fwrite(STDERR, "❌ ERROR: Missing required parameters.\n"); 126 | fwrite(STDOUT, "Usage: php MCPLoginClient.php --server-ip <IP> --server-port <Port> --email <Email> --password <Password>\n"); 127 | exit(1); 128 | } 129 | 130 | $payload = [ 131 | "command" => "login", 132 | "arguments" => [ 133 | "email" => $email, 134 | "password" => $password 135 | ] 136 | ]; 137 | 138 | try { 139 | echo "🔐 Logging in...\n"; 140 | $response = sendRequest($serverIp, $serverPort, $payload); 141 | echo "✅ Server Response:\n"; 142 | echo json_encode($response, JSON_PRETTY_PRINT) . "\n"; 143 | } catch (Exception $e) { 144 | fwrite(STDERR, "❌ ERROR: " . $e->getMessage() . "\n"); 145 | } 146 | } 147 | 148 | main($argv); 149 | ?> 150 | ``` -------------------------------------------------------------------------------- /clients/PHP/1.1 mcp_logout/MCPLogoutClient.php: -------------------------------------------------------------------------------- ```php 1 | <?php 2 | // Functions for parsing command line arguments 3 | function parseArguments($args) { 4 | $parsedArgs = []; 5 | $argc = count($args); 6 | for ($i = 1; $i < $argc; $i++) { 7 | switch ($args[$i]) { 8 | case '--server-ip': 9 | if (isset($args[$i + 1])) { 10 | $parsedArgs['serverIp'] = $args[++$i]; 11 | } else { 12 | fwrite(STDERR, "Error: --server-ip expects a value.\n"); 13 | exit(1); 14 | } 15 | break; 16 | case '--server-port': 17 | if (isset($args[$i + 1])) { 18 | $parsedArgs['serverPort'] = intval($args[++$i]); 19 | } else { 20 | fwrite(STDERR, "Error: --server-port expects a value.\n"); 21 | exit(1); 22 | } 23 | break; 24 | case '--token': 25 | if (isset($args[$i + 1])) { 26 | $parsedArgs['token'] = $args[++$i]; 27 | } else { 28 | fwrite(STDERR, "Error: --token expects a value.\n"); 29 | exit(1); 30 | } 31 | break; 32 | default: 33 | fwrite(STDERR, "Warning: Unknown argument: {$args[$i]}\n"); 34 | } 35 | } 36 | return $parsedArgs; 37 | } 38 | 39 | // Function for interactively asking for a token (optional) 40 | function askToken($prompt) { 41 | if (preg_match('/^win/i', PHP_OS)) { 42 | // Windows-specific token prompt 43 | $vbscript = sys_get_temp_dir() . 'prompt_token.vbs'; 44 | file_put_contents($vbscript, 'wscript.echo(InputBox("' . addslashes($prompt) . '", "", "token here"))'); 45 | $token = shell_exec("cscript //nologo " . escapeshellarg($vbscript)); 46 | unlink($vbscript); 47 | return trim($token); 48 | } else { 49 | // Unix/Linux token prompt 50 | echo $prompt; 51 | // Token input typically without echo 52 | if (shell_exec('which stty')) { 53 | system('stty -echo'); 54 | $token = rtrim(fgets(STDIN), "\n"); 55 | system('stty echo'); 56 | echo "\n"; 57 | return $token; 58 | } else { 59 | // Fallback if stty is unavailable 60 | return rtrim(fgets(STDIN), "\n"); 61 | } 62 | } 63 | } 64 | 65 | // Function for sending a logout request over a TCP connection 66 | function sendLogoutRequest($serverIp, $serverPort, $payload) { 67 | $jsonPayload = json_encode($payload); 68 | if ($jsonPayload === false) { 69 | throw new Exception("Error encoding JSON payload."); 70 | } 71 | 72 | $errno = 0; 73 | $errstr = ''; 74 | $timeout = 30; // seconds 75 | $client = fsockopen($serverIp, $serverPort, $errno, $errstr, $timeout); 76 | 77 | if (!$client) { 78 | throw new Exception("Connection error: $errstr ($errno)"); 79 | } 80 | 81 | echo "🔗 Connection to server established.\n"; 82 | 83 | fwrite($client, $jsonPayload); 84 | 85 | $responseData = ''; 86 | stream_set_timeout($client, $timeout); 87 | 88 | while (!feof($client)) { 89 | $data = fread($client, 1024); 90 | if ($data === false) { 91 | throw new Exception("Error reading data from server."); 92 | } 93 | $responseData .= $data; 94 | 95 | // Attempt to parse the received data as JSON 96 | $parsedData = json_decode($responseData, true); 97 | if ($parsedData !== null) { 98 | fclose($client); 99 | return $parsedData; 100 | } 101 | 102 | // Check if the stream timed out 103 | $info = stream_get_meta_data($client); 104 | if ($info['timed_out']) { 105 | throw new Exception("Timeout waiting for data from server."); 106 | } 107 | } 108 | 109 | fclose($client); 110 | throw new Exception("Connection to the server was closed before a complete response was received."); 111 | } 112 | 113 | // Main function 114 | function main($argv) { 115 | $args = parseArguments($argv); 116 | $serverIp = $args['serverIp'] ?? null; 117 | $serverPort = $args['serverPort'] ?? null; 118 | $token = $args['token'] ?? null; 119 | 120 | // Check if all required parameters except token are present 121 | if (!$serverIp || !$serverPort) { 122 | fwrite(STDERR, "❌ ERROR: Missing required parameters.\n"); 123 | fwrite(STDOUT, "Usage: php MCPLogoutClient.php --server-ip <IP> --server-port <Port> --token <Token>\n"); 124 | exit(1); 125 | } 126 | 127 | // Interactively ask for token if not provided in arguments 128 | $authToken = $token; 129 | if (!$authToken) { 130 | $authToken = askToken('🔒 Please enter your authentication token: '); 131 | } 132 | 133 | if (empty($authToken)) { 134 | fwrite(STDERR, "❌ ERROR: Authentication token must not be empty.\n"); 135 | exit(1); 136 | } 137 | 138 | $payload = [ 139 | "command" => "logout", 140 | "token" => $authToken 141 | ]; 142 | 143 | try { 144 | echo "🚪 Logging out...\n"; 145 | $response = sendLogoutRequest($serverIp, $serverPort, $payload); 146 | echo "✅ Server Response:\n"; 147 | echo json_encode($response, JSON_PRETTY_PRINT) . "\n"; 148 | } catch (Exception $e) { 149 | fwrite(STDERR, "❌ ERROR: " . $e->getMessage() . "\n"); 150 | } 151 | } 152 | 153 | main($argv); 154 | ?> 155 | ``` -------------------------------------------------------------------------------- /clients/C++/5.0 mcp_store_user/MCPStoreUserClient.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 | // Argumente auslesen 105 | std::string serverIp = args["--server-ip"]; 106 | int serverPort = std::stoi(args["--server-port"]); 107 | std::string token = args["--token"]; 108 | std::string name = args["--name"]; 109 | std::string email = args["--email"]; 110 | std::string password = args["--password"]; 111 | std::string language = args.count("--language") ? args["--language"] : "en"; 112 | std::string timezone = args.count("--timezone") ? args["--timezone"] : "Europe/Berlin"; 113 | auto roles = parseListArgument(argc, argv, "--roles"); 114 | auto groups = parseListArgument(argc, argv, "--groups"); 115 | bool usePublic = args.count("--usePublic"); 116 | bool activateFtp = args.count("--activateFtp"); 117 | std::string ftpPassword = args.count("--ftpPassword") ? args["--ftpPassword"] : ""; 118 | 119 | // JSON-Payload erstellen 120 | Json::Value payload; 121 | payload["command"] = "store_user"; 122 | payload["token"] = token; 123 | payload["arguments"]["name"] = name; 124 | payload["arguments"]["email"] = email; 125 | payload["arguments"]["password"] = password; 126 | payload["arguments"]["language"] = language; 127 | payload["arguments"]["timezone"] = timezone; 128 | for (const auto& role : roles) { 129 | payload["arguments"]["roles"].append(role); 130 | } 131 | for (const auto& group : groups) { 132 | payload["arguments"]["groups"].append(group); 133 | } 134 | payload["arguments"]["usePublic"] = usePublic; 135 | payload["arguments"]["activateFtp"] = activateFtp; 136 | payload["arguments"]["ftpPassword"] = ftpPassword; 137 | 138 | std::cout << "📤 Sending store user request...\n"; 139 | 140 | // Anfrage senden und Antwort erhalten 141 | std::string response = sendRequest(serverIp, serverPort, payload); 142 | 143 | std::cout << "✔️ Response from server:\n" << response << "\n"; 144 | } catch (const std::exception& e) { 145 | std::cerr << "❌ ERROR: " << e.what() << "\n"; 146 | return 1; 147 | } 148 | 149 | return 0; 150 | } 151 | ``` -------------------------------------------------------------------------------- /agents/IoTAgent/Python/language.py: -------------------------------------------------------------------------------- ```python 1 | # language.py 2 | languages = { 3 | "en": { 4 | "configuration_loaded": "Configuration loaded from {config_path}.", 5 | "error_loading_config": "Error loading configuration: {e}", 6 | "welcome": "Connected to MQTT broker successfully.", 7 | "chatbot_error_status": "Chatbot returned error status {status_code}.", 8 | "start_uploading_file": "Starting upload for file: {file_path}.", 9 | "error_sftp_upload": "Error uploading file {file_path}: {e}", 10 | "file_archived": "File {file_path} archived as {archive_name}.", 11 | "error_archiving_file": "Error archiving file {file_path}: {e}", 12 | "file_size": "File {file_path} size: {file_size} bytes.", 13 | "file_limit_reached": "File {file_path} reached size limit of {size_limit} bytes.", 14 | "new_file_created": "New file created at {file_path}.", 15 | "cannot_create_new_file": "Cannot create new file of type {file_type} for language {language}.", 16 | "error_getting_suffixes": "Error getting suffixes: {e}", 17 | "record_added": "Record added to {file_path}.", 18 | "invalid_group": "Invalid group type: {groups}.", 19 | "error_writing_file": "Error writing to file {file_path}: {e}", 20 | "file_empty_or_corrupted": "File {file_path} is empty or corrupted.", 21 | "language_sentence_generated": "Language: {language_full} | Sentence: {sentence}", 22 | "no_translation_file_config": "No translation file configured for language {language}.", 23 | "no_file_handler_found": "No file handler found for language {language}.", 24 | "no_translation_file_in_config": "No translation file configured in config for language {language}.", 25 | "empty_answer_field": "Warning: 'answer' field is empty in the chatbot response.", 26 | "max_retries_reached": "Maximum retry attempts reached.", 27 | "communication_error": "Communication error: {e} | Attempt {attempt} of {max_retries}.", 28 | "waiting_before_retry": "Waiting {wait_seconds} seconds before retrying...", 29 | "error_in_interpret_and_output": "Error in interpret_and_output: {e}", 30 | "sending_request_to_chatbot": "Sending request to chatbot (Attempt {attempt}).", 31 | "chatbot_response": "Chatbot response: {response}", 32 | "unknown_language": "Unknown language: {language}.", 33 | "no_sentence_generated": "No sentence generated for language {language_full}.", 34 | "user_exit": "User initiated exit." 35 | }, 36 | "de": { 37 | "configuration_loaded": "Konfiguration geladen von {config_path}.", 38 | "error_loading_config": "Fehler beim Laden der Konfiguration: {e}", 39 | "welcome": "Erfolgreich mit dem MQTT-Broker verbunden.", 40 | "chatbot_error_status": "Chatbot hat Fehlerstatus {status_code} zurückgegeben.", 41 | "start_uploading_file": "Starte Upload für Datei: {file_path}.", 42 | "error_sftp_upload": "Fehler beim Hochladen der Datei {file_path}: {e}", 43 | "file_archived": "Datei {file_path} archiviert als {archive_name}.", 44 | "error_archiving_file": "Fehler beim Archivieren der Datei {file_path}: {e}", 45 | "file_size": "Datei {file_path} Größe: {file_size} Bytes.", 46 | "file_limit_reached": "Datei {file_path} hat das Größenlimit von {size_limit} Bytes erreicht.", 47 | "new_file_created": "Neue Datei erstellt unter {file_path}.", 48 | "cannot_create_new_file": "Kann keine neue Datei vom Typ {file_type} für Sprache {language} erstellen.", 49 | "error_getting_suffixes": "Fehler beim Abrufen der Suffixe: {e}", 50 | "record_added": "Datensatz hinzugefügt zu {file_path}.", 51 | "invalid_group": "Ungültiger Gruppentyp: {groups}.", 52 | "error_writing_file": "Fehler beim Schreiben in die Datei {file_path}: {e}", 53 | "file_empty_or_corrupted": "Datei {file_path} ist leer oder beschädigt.", 54 | "language_sentence_generated": "Sprache: {language_full} | Satz: {sentence}", 55 | "no_translation_file_config": "Keine Übersetzungsdatei für Sprache {language} konfiguriert.", 56 | "no_file_handler_found": "Kein Dateihandler für Sprache {language} gefunden.", 57 | "no_translation_file_in_config": "Keine Übersetzungsdatei in der Konfiguration für Sprache {language} konfiguriert.", 58 | "empty_answer_field": "Warnung: 'answer'-Feld ist in der Chatbot-Antwort leer.", 59 | "max_retries_reached": "Maximale Anzahl an Wiederholungsversuchen erreicht.", 60 | "communication_error": "Kommunikationsfehler: {e} | Versuch {attempt} von {max_retries}.", 61 | "waiting_before_retry": "Warte {wait_seconds} Sekunden bevor erneut versucht wird...", 62 | "error_in_interpret_and_output": "Fehler in interpret_and_output: {e}", 63 | "sending_request_to_chatbot": "Sende Anfrage an Chatbot (Versuch {attempt}).", 64 | "chatbot_response": "Chatbot-Antwort: {response}", 65 | "unknown_language": "Unbekannte Sprache: {language}.", 66 | "no_sentence_generated": "Kein Satz für Sprache {language_full} generiert.", 67 | "user_exit": "Benutzer hat die Anwendung beendet." 68 | } 69 | } 70 | ``` -------------------------------------------------------------------------------- /clients/Java/3.0 mcp_create_source/MCPCreateSourceClient.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.List; 11 | 12 | public class MCPCreateSourceClient { 13 | 14 | public static void main(String[] args) { 15 | // Entspricht dem Minimalcheck (8 Parameter) wie im C#-Code. 16 | if (args.length < 8) { 17 | printUsage(); 18 | return; 19 | } 20 | 21 | String serverIp = getArgument(args, "--server-ip"); 22 | String portStr = getArgument(args, "--server-port"); 23 | String token = getArgument(args, "--token"); 24 | String name = getArgument(args, "--name"); 25 | String content = getArgument(args, "--content"); 26 | List<String> groups = getArgumentList(args, "--groups"); 27 | 28 | // Falls wichtige Argumente fehlen, direkt Usage anzeigen 29 | if (serverIp == null || portStr == null || token == null 30 | || name == null || content == null) { 31 | printUsage(); 32 | return; 33 | } 34 | 35 | int serverPort = Integer.parseInt(portStr); 36 | 37 | System.out.println("📤 Sending request to create a new source..."); 38 | 39 | // JSON-Payload erstellen 40 | JSONObject payload = new JSONObject(); 41 | payload.put("command", "create_source"); 42 | payload.put("token", token); 43 | 44 | // "arguments" Objekt 45 | JSONObject arguments = new JSONObject(); 46 | arguments.put("name", name); 47 | arguments.put("content", content); 48 | 49 | // "groups" als JSONArray hinzufügen 50 | JSONArray groupsJsonArray = new JSONArray(groups); 51 | arguments.put("groups", groupsJsonArray); 52 | 53 | payload.put("arguments", arguments); 54 | 55 | // Request an den MCP-Server senden 56 | String response = sendRequest(serverIp, serverPort, payload); 57 | System.out.println("✔️ Response from server:"); 58 | System.out.println(response); 59 | } 60 | 61 | /** 62 | * Gibt einen einzelnen Argumentwert für das gegebene Schlüsselwort zurück, 63 | * oder null, wenn keiner gefunden wurde. 64 | */ 65 | private static String getArgument(String[] args, String key) { 66 | for (int i = 0; i < args.length - 1; i++) { 67 | if (args[i].equals(key)) { 68 | return args[i + 1]; 69 | } 70 | } 71 | return null; 72 | } 73 | 74 | /** 75 | * Sucht im args-Array nach dem Schlüssel 'key' und liest dann solange 76 | * weiter, bis das nächste Argument wieder mit "--" beginnt (oder das Array endet). 77 | * So können mehrere Gruppenwerte nacheinander gelesen werden. 78 | */ 79 | private static List<String> getArgumentList(String[] args, String key) { 80 | List<String> values = new ArrayList<>(); 81 | for (int i = 0; i < args.length; i++) { 82 | if (args[i].equals(key)) { 83 | // Ab hier die folgenden Einträge sammeln, bis "--" oder Ende 84 | for (int j = i + 1; j < args.length; j++) { 85 | if (args[j].startsWith("--")) { 86 | break; 87 | } 88 | values.add(args[j]); 89 | } 90 | break; // Suche beenden, sobald wir die Liste gefunden haben 91 | } 92 | } 93 | return values; 94 | } 95 | 96 | /** 97 | * Baut eine Socket-Verbindung zum Server auf, sendet das JSON-Payload 98 | * und empfängt die Antwort. 99 | */ 100 | private static String sendRequest(String serverIp, int serverPort, JSONObject payload) { 101 | String payloadJson = payload.toString(); 102 | 103 | try (Socket client = new Socket(serverIp, serverPort)) { 104 | // Daten senden 105 | OutputStream out = client.getOutputStream(); 106 | byte[] data = payloadJson.getBytes(StandardCharsets.UTF_8); 107 | out.write(data); 108 | out.flush(); 109 | 110 | // Antwort empfangen 111 | InputStream in = client.getInputStream(); 112 | byte[] buffer = new byte[4096]; 113 | StringBuilder responseBuilder = new StringBuilder(); 114 | int bytesRead; 115 | 116 | do { 117 | bytesRead = in.read(buffer); 118 | if (bytesRead > 0) { 119 | responseBuilder.append(new String(buffer, 0, bytesRead, StandardCharsets.UTF_8)); 120 | } 121 | } while (bytesRead == buffer.length); 122 | 123 | return responseBuilder.toString(); 124 | 125 | } catch (IOException e) { 126 | return "Error: " + e.getMessage(); 127 | } 128 | } 129 | 130 | private static void printUsage() { 131 | System.out.println("Usage:"); 132 | System.out.println(" --server-ip <IP> --server-port <PORT> --token <TOKEN> " 133 | + "--name <NAME> --content <CONTENT> [--groups <GROUP1 GROUP2 ...>]"); 134 | System.out.println(); 135 | System.out.println("Example:"); 136 | System.out.println(" java -cp .;json-20241224.jar MCPCreateSourceClient " 137 | + "--server-ip 127.0.0.1 --server-port 1234 --token MyToken " 138 | + "--name \"Test Source\" --content \"This is some content\" " 139 | + "--groups dev hr admin"); 140 | } 141 | } 142 | ``` -------------------------------------------------------------------------------- /WORKLOG.md: -------------------------------------------------------------------------------- ```markdown 1 | # PrivateGPT MCP Server Development Log 2 | 3 | ## ⚠️ Warning: User Management Implementation 4 | 5 | **HANDLE WITH CARE**: The user management endpoints have significant impact and can potentially delete all users if not handled properly. While the API functionality has been tested successfully, implementation in the pgpt-mcp-server is pending due to these security considerations. 6 | 7 | The following user management endpoints require careful implementation: 8 | 9 | ### Create User (POST /api/v1/users) 10 | Required functionality: 11 | - Create new user with name, email, and password 12 | - Set optional language and timezone 13 | - Configure public access and group assignments 14 | - Assign user roles 15 | - Set up FTP access if needed 16 | - Handle all required fields: 17 | ```json 18 | { 19 | "name": "User Name", 20 | "email": "[email protected]", 21 | "password": "UserPassword123", 22 | "language": "en", 23 | "timezone": "UTC", 24 | "usePublic": true, 25 | "groups": ["Group A"], 26 | "roles": ["Sources"], 27 | "activateFtp": true, 28 | "ftpPassword": "FTPPassword!" 29 | } 30 | ``` 31 | 32 | ### Edit User (PATCH /api/v1/users) 33 | Required functionality: 34 | - Update user details by email 35 | - Modify name, language, and group assignments 36 | - Handle partial updates 37 | - Fields that can be updated: 38 | ```json 39 | { 40 | "email": "[email protected]", 41 | "name": "Updated Name", 42 | "language": "en", 43 | "groups": ["Updated Group"] 44 | } 45 | ``` 46 | 47 | ### Delete User (DELETE /api/v1/users) 48 | ⚠️ **Critical Operation** 49 | Required functionality: 50 | - Remove user by email 51 | - Clean up associated data 52 | - Handle dependencies: 53 | ```json 54 | { 55 | "email": "[email protected]" 56 | } 57 | ``` 58 | 59 | ## Implementation Status 60 | 61 | ### Core Server Structure 62 | - ✅ Basic MCP server setup with stdio transport 63 | - ✅ Error handling and graceful shutdown 64 | - ✅ Type-safe request handling 65 | - ✅ Input validation for all tools 66 | 67 | ### API Integration 68 | - ✅ Authentication with Bearer tokens 69 | - ✅ Automatic token refresh 70 | - ✅ Error mapping to MCP error codes 71 | - ✅ JSON response formatting 72 | 73 | ### Tools Implementation 74 | 1. Chat Tool 75 | - ✅ Chat creation with knowledge base selection 76 | - ✅ Support for public and document knowledge bases 77 | - ✅ Group-based access control 78 | - ✅ Language support 79 | - ✅ Chat continuation support 80 | 81 | 2. Source Management 82 | - ✅ Source creation with markdown formatting 83 | - ✅ Group assignment for private sources 84 | - ✅ Source listing by group 85 | - ✅ Source details retrieval 86 | - ✅ Source deletion 87 | - ✅ Source editing 88 | 89 | 3. Group Management 90 | - ✅ List personal and assignable groups 91 | - ✅ Group-based visibility control 92 | - ✅ Personal group handling 93 | - ✅ Group creation 94 | - ✅ Group deletion 95 | 96 | ## API Behavior Notes 97 | 98 | ### Authentication 99 | - Uses Bearer token authentication via `/api/v1/login` 100 | - Token required for all authenticated endpoints 101 | - Token invalidation via `/api/v1/logout` 102 | 103 | ### Group Management 104 | - GET `/api/v1/groups` returns personalGroups and assignableGroups arrays 105 | - Personal group appears in both arrays 106 | - Groups control access to sources and knowledge base 107 | - Full CRUD operations implemented and tested 108 | 109 | ### Source Management 110 | - Sources can be public or private 111 | - Private sources require group assignment 112 | - Sources are vectorized asynchronously 113 | - Source states: creation → vectorized 114 | - Source operations: 115 | - POST `/api/v1/sources` for creation 116 | - DELETE `/api/v1/sources/{sourceId}` for removal 117 | - PATCH `/api/v1/sources/{sourceId}` for editing 118 | - Can list sources by group 119 | - Can verify source state and visibility 120 | - All operations tested and verified 121 | 122 | ### Chat System 123 | - Two knowledge base types: 124 | - Public (usePublic: true) 125 | - Document (specific groups) 126 | - Chat operations: 127 | - Initial creation: POST `/api/v1/chats` 128 | - Continuation: PATCH `/api/v1/chats/{chatId}` 129 | - Details: GET `/api/v1/chats/{chatId}` 130 | - Chat features: 131 | - Preserves complete message history 132 | - Context-aware responses 133 | - Group-based access control 134 | - Language support 135 | 136 | ## Implementation Details 137 | 138 | ### Type Safety 139 | - Comprehensive TypeScript interfaces for all API interactions 140 | - Runtime validation for all tool inputs 141 | - Error type mapping between API and MCP 142 | 143 | ### Error Handling 144 | - API errors mapped to appropriate MCP error codes 145 | - Detailed error messages preserved 146 | - Authentication errors handled gracefully 147 | 148 | ### Resource Management 149 | - No direct resource exposure currently 150 | - All data access through tools 151 | - Future potential for direct resource access 152 | 153 | ## Future Improvements 154 | 1. Performance Optimizations: 155 | - Add caching layer 156 | - Optimize API requests 157 | - Improve response times 158 | 159 | 2. Monitoring and Observability: 160 | - Add comprehensive logging 161 | - Add metrics collection 162 | - Add performance tracking 163 | 164 | 3. Documentation: 165 | - Add API reference documentation 166 | - Add deployment guides 167 | - Add troubleshooting guides 168 | 169 | 4. Security Enhancements: 170 | - Add rate limiting 171 | - Implement request validation 172 | - Add security headers 173 | - Enhance token management 174 | - Add user session management 175 | 176 | ## Testing Notes 177 | - ✅ All major API endpoints tested 178 | - ✅ Group-based access control verified 179 | - ✅ Chat system behavior documented 180 | - ✅ Source visibility rules confirmed 181 | - ✅ Error handling validated 182 | - ✅ Source CRUD operations verified 183 | - ✅ Group CRUD operations verified 184 | - ✅ User management API functionality tested 185 | ``` -------------------------------------------------------------------------------- /clients/C++/1.0 mcp_login/MCPLoginClient.cpp: -------------------------------------------------------------------------------- ```cpp 1 | #include <iostream> 2 | #include <string> 3 | #include <map> 4 | #include <cstring> 5 | #include <cstdlib> 6 | #include <sstream> 7 | #include <stdexcept> 8 | #include <json/json.h> 9 | #include <openssl/ssl.h> 10 | #include <openssl/err.h> 11 | 12 | #ifdef _WIN32 13 | #include <winsock2.h> 14 | #include <ws2tcpip.h> 15 | #pragma comment(lib, "ws2_32.lib") 16 | #pragma comment(lib, "libssl.lib") 17 | #pragma comment(lib, "libcrypto.lib") 18 | #else 19 | #include <sys/socket.h> 20 | #include <arpa/inet.h> 21 | #include <unistd.h> 22 | #endif 23 | 24 | // Function to parse command-line arguments 25 | std::map<std::string, std::string> parseArguments(int argc, char* argv[]) { 26 | std::map<std::string, std::string> args; 27 | for (int i = 1; i < argc; i++) { 28 | std::string key = argv[i]; 29 | if (i + 1 < argc) { 30 | args[key] = argv[++i]; 31 | } 32 | } 33 | return args; 34 | } 35 | 36 | void init_openssl() { 37 | SSL_load_error_strings(); 38 | OpenSSL_add_ssl_algorithms(); 39 | } 40 | 41 | void cleanup_openssl() { 42 | EVP_cleanup(); 43 | } 44 | 45 | SSL_CTX* create_context() { 46 | const SSL_METHOD* method; 47 | SSL_CTX* ctx; 48 | 49 | method = TLS_client_method(); 50 | ctx = SSL_CTX_new(method); 51 | if (!ctx) { 52 | perror("Unable to create SSL context"); 53 | ERR_print_errors_fp(stderr); 54 | exit(EXIT_FAILURE); 55 | } 56 | 57 | return ctx; 58 | } 59 | 60 | std::string sendRequest(const std::string& serverIp, int serverPort, const Json::Value& payload) { 61 | init_openssl(); 62 | SSL_CTX* ctx = create_context(); 63 | 64 | #ifdef _WIN32 65 | WSADATA wsaData; 66 | WSAStartup(MAKEWORD(2,2), &wsaData); 67 | #endif 68 | 69 | int sock = socket(AF_INET, SOCK_STREAM, 0); 70 | if (sock < 0) { 71 | SSL_CTX_free(ctx); 72 | #ifdef _WIN32 73 | WSACleanup(); 74 | #endif 75 | throw std::runtime_error("Failed to create socket"); 76 | } 77 | 78 | struct sockaddr_in serverAddr; 79 | serverAddr.sin_family = AF_INET; 80 | serverAddr.sin_port = htons(serverPort); 81 | if (inet_pton(AF_INET, serverIp.c_str(), &serverAddr.sin_addr) <= 0) { 82 | #ifdef _WIN32 83 | closesocket(sock); 84 | WSACleanup(); 85 | #else 86 | close(sock); 87 | #endif 88 | SSL_CTX_free(ctx); 89 | throw std::runtime_error("Invalid server IP address"); 90 | } 91 | 92 | if (connect(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { 93 | #ifdef _WIN32 94 | closesocket(sock); 95 | WSACleanup(); 96 | #else 97 | close(sock); 98 | #endif 99 | SSL_CTX_free(ctx); 100 | throw std::runtime_error("Connection failed"); 101 | } 102 | 103 | SSL* ssl = SSL_new(ctx); 104 | SSL_set_fd(ssl, sock); 105 | if (SSL_connect(ssl) <= 0) { 106 | ERR_print_errors_fp(stderr); 107 | #ifdef _WIN32 108 | closesocket(sock); 109 | WSACleanup(); 110 | #else 111 | close(sock); 112 | #endif 113 | SSL_free(ssl); 114 | SSL_CTX_free(ctx); 115 | throw std::runtime_error("Failed to create SSL connection"); 116 | } 117 | 118 | // Serialize the JSON payload to a string 119 | Json::StreamWriterBuilder writer; 120 | std::string payloadJson = Json::writeString(writer, payload); 121 | 122 | // Send the payload 123 | if (SSL_write(ssl, payloadJson.c_str(), payloadJson.size()) <= 0) { 124 | #ifdef _WIN32 125 | closesocket(sock); 126 | WSACleanup(); 127 | #else 128 | close(sock); 129 | #endif 130 | SSL_free(ssl); 131 | SSL_CTX_free(ctx); 132 | throw std::runtime_error("Failed to send data"); 133 | } 134 | 135 | // Receive the response 136 | char buffer[4096]; 137 | int bytesRead = SSL_read(ssl, buffer, sizeof(buffer) - 1); 138 | if (bytesRead < 0) { 139 | #ifdef _WIN32 140 | closesocket(sock); 141 | WSACleanup(); 142 | #else 143 | close(sock); 144 | #endif 145 | SSL_free(ssl); 146 | SSL_CTX_free(ctx); 147 | throw std::runtime_error("Failed to receive data"); 148 | } 149 | 150 | buffer[bytesRead] = '\0'; // Null-terminate the received data 151 | 152 | SSL_free(ssl); 153 | #ifdef _WIN32 154 | closesocket(sock); 155 | WSACleanup(); 156 | #else 157 | close(sock); 158 | #endif 159 | SSL_CTX_free(ctx); 160 | cleanup_openssl(); 161 | 162 | return std::string(buffer); 163 | } 164 | 165 | int main(int argc, char* argv[]) { 166 | try { 167 | auto args = parseArguments(argc, argv); 168 | 169 | // Extract required parameters 170 | std::string serverIp = args["--server-ip"]; 171 | int serverPort = std::stoi(args["--server-port"]); 172 | std::string email = args["--email"]; 173 | std::string password = args["--password"]; 174 | 175 | if (serverIp.empty() || serverPort == 0 || email.empty() || password.empty()) { 176 | std::cerr << "❌ ERROR: Missing required parameters.\n"; 177 | return 1; 178 | } 179 | 180 | std::cout << "🔐 Logging in...\n"; 181 | 182 | // Build the payload 183 | Json::Value payload; 184 | payload["command"] = "login"; 185 | payload["arguments"]["email"] = email; 186 | payload["arguments"]["password"] = password; 187 | 188 | // Send request and get response 189 | std::string responseJson = sendRequest(serverIp, serverPort, payload); 190 | 191 | // Parse and print the server response 192 | Json::CharReaderBuilder reader; 193 | Json::Value response; 194 | std::istringstream responseStream(responseJson); 195 | std::string errs; 196 | 197 | if (!Json::parseFromStream(reader, responseStream, &response, &errs)) { 198 | throw std::runtime_error("Failed to parse server response: " + errs); 199 | } 200 | 201 | std::cout << "✅ Server Response:\n" << response.toStyledString(); 202 | } catch (const std::exception& e) { 203 | std::cerr << "❌ ERROR: " << e.what() << '\n'; 204 | return 1; 205 | } 206 | 207 | return 0; 208 | } 209 | ``` -------------------------------------------------------------------------------- /src/logger.js: -------------------------------------------------------------------------------- ```javascript 1 | // logger.js 2 | import winston from 'winston'; 3 | import chalk from 'chalk'; 4 | import stripAnsi from 'strip-ansi'; 5 | import fs from 'fs'; 6 | import path from 'path'; 7 | import { fileURLToPath } from 'url'; 8 | 9 | // ESM-Äquivalent von __dirname 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = path.dirname(__filename); 12 | 13 | // Bestimmen Sie den Pfad zur Log-Datei relativ zu `logger.js` 14 | const LOG_FILE_PATH = path.join(__dirname, '../logs/server.log'); // Passen Sie den Pfad nach Bedarf an 15 | 16 | // Hilfsfunktionen für Symbole und Farben 17 | function getLevelSymbol(level) { 18 | const symbols = { 19 | info: 'ℹ️', 20 | warn: '⚠️', 21 | error: '❌', 22 | debug: '🐞', 23 | }; 24 | return symbols[level] || ''; 25 | } 26 | 27 | function chalkForLevel(level) { 28 | const levels = { 29 | info: chalk.blue, 30 | warn: chalk.yellow, 31 | error: chalk.red, 32 | debug: chalk.green, 33 | }; 34 | return levels[level] || chalk.white; 35 | } 36 | 37 | // Variable zur Steuerung der Dateiausgabe 38 | let allowWrittenLogfile = false; 39 | 40 | // Initialisieren der Transports mit nur der Konsolenausgabe 41 | const transports = [ 42 | new winston.transports.Console({ 43 | format: winston.format.combine( 44 | winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), 45 | winston.format.printf(({ timestamp, level, message }) => { 46 | const symbol = getLevelSymbol(level); 47 | const coloredMessage = `${chalkForLevel(level)(symbol)} ${message}`; 48 | return `${timestamp} | ${coloredMessage}`; 49 | }) 50 | ), 51 | }), 52 | ]; 53 | 54 | // Erstellen des Winston-Loggers 55 | const logger = winston.createLogger({ 56 | level: 'info', 57 | transports: transports, 58 | }); 59 | 60 | /** 61 | * Funktion zum Hinzufügen des File-Transports 62 | */ 63 | function addFileTransport() { 64 | const logDir = path.dirname(LOG_FILE_PATH); 65 | if (!fs.existsSync(logDir)) { 66 | fs.mkdirSync(logDir, { recursive: true }); 67 | } 68 | 69 | const fileTransport = new winston.transports.File({ 70 | filename: LOG_FILE_PATH, 71 | level: 'info', // Stellen Sie sicher, dass der Level ausreichend niedrig ist 72 | maxsize: 10485760, // 10 MB pro Datei 73 | maxFiles: 5, // Maximal 5 Dateien 74 | format: winston.format.combine( 75 | winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), 76 | winston.format.printf(({ timestamp, level, message }) => { 77 | const symbol = getLevelSymbol(level); 78 | const plainMessage = stripAnsi(`${symbol} ${message}`); // ANSI-Codes entfernen 79 | return `${timestamp} | ${plainMessage}`; 80 | }) 81 | ), 82 | }); 83 | 84 | // Fehler-Handler hinzufügen 85 | fileTransport.on('error', (error) => { 86 | console.error(chalk.red('File-Transport Fehler:'), error); 87 | }); 88 | 89 | // Prüfen, ob der Transport bereits hinzugefügt wurde, um Duplikate zu vermeiden 90 | if (!logger.transports.some(t => t instanceof winston.transports.File)) { 91 | logger.add(fileTransport); 92 | } 93 | } 94 | 95 | /** 96 | * Funktion zum Entfernen des File-Transports 97 | */ 98 | function removeFileTransport() { 99 | const fileTransport = logger.transports.find( 100 | (t) => t instanceof winston.transports.File 101 | ); 102 | if (fileTransport) { 103 | logger.remove(fileTransport); 104 | } 105 | } 106 | 107 | /** 108 | * Funktion zum Setzen von allowWrittenLogfile 109 | * @param {boolean} value - true, um Dateilogs zu erlauben; false, um sie zu deaktivieren 110 | */ 111 | function setAllowWrittenLogfile(value) { 112 | allowWrittenLogfile = value; 113 | if (allowWrittenLogfile) { 114 | addFileTransport(); 115 | logEvent('system', 'wrlog', 'File logs activated.', 'File logs are now activated.', 'info'); 116 | 117 | // Überprüfen, ob der File-Transport hinzugefügt wurde 118 | const fileTransport = logger.transports.find(t => t instanceof winston.transports.File); 119 | if (fileTransport) { 120 | // console.log(chalk.green('File-Transport erfolgreich hinzugefügt.')); 121 | } else { 122 | console.log(chalk.red('Error: File transport could not be added.')); 123 | } 124 | } else { 125 | removeFileTransport(); 126 | logEvent('system', 'wrlog', 'File logs deactivated.', 'File logs are now deactivated.', 'info'); 127 | } 128 | } 129 | 130 | /** 131 | * Zentrale Logging-Funktion 132 | * @param {string} clientIP - IP-Adresse des Clients 133 | * @param {number|string} clientPort - Port des Clients 134 | * @param {string} functionName - Name der aufgerufenen Funktion 135 | * @param {string|object} status - Status der Rückmeldung 136 | * @param {string} level - Log-Level ('info', 'warn', 'error', 'debug') 137 | */ 138 | function logEvent(clientIP, clientPort, functionName, status, level = 'info') { 139 | // Kürzen und formatieren der Felder 140 | const ip = String(clientIP || 'N/A').padEnd(23).substring(0, 23); // Mindestens 8 Zeichen für die IP 141 | const port = String(clientPort || 'N/A').padEnd(5).substring(0, 5); // 5 Zeichen für den Port 142 | const func = String(functionName || 'N/A').padEnd(26).substring(0, 26); // 20 Zeichen für den Funktionsnamen 143 | const stat = String(status || '').padEnd(120).substring(0, 120); // 100 Zeichen für den Status 144 | 145 | // Formatierte Logzeile 146 | const logLine = `${ip}:${port} | ${func} | ${stat}`; 147 | // Log-Ausgabe basierend auf dem Level 148 | logger.log({ level, message: logLine }); 149 | } 150 | 151 | 152 | export { logger, logEvent, setAllowWrittenLogfile, LOG_FILE_PATH }; 153 | ```