mcp-proxy-adapter 6.7.2__tar.gz → 6.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/PKG-INFO +1 -1
  2. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/app.py +14 -0
  3. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/app_factory.py +41 -55
  4. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/mtls_server.py +5 -1
  5. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/signal_handler.py +6 -4
  6. mcp_proxy_adapter-6.8.0/mcp_proxy_adapter/core/utils.py +282 -0
  7. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/basic_framework/main.py +10 -11
  8. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/main.py +12 -62
  9. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/main.py +22 -0
  10. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/version.py +1 -1
  11. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/PKG-INFO +1 -1
  12. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/SOURCES.txt +0 -4
  13. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/pyproject.toml +1 -1
  14. mcp_proxy_adapter-6.7.2/mcp_proxy_adapter/core/async_proxy_registration.py +0 -285
  15. mcp_proxy_adapter-6.7.2/mcp_proxy_adapter/core/utils.py +0 -140
  16. mcp_proxy_adapter-6.7.2/mcp_proxy_adapter/examples/generate_certificates.py +0 -385
  17. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/README.md +0 -0
  18. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/__init__.py +0 -0
  19. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/__main__.py +0 -0
  20. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/__init__.py +0 -0
  21. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/handlers.py +0 -0
  22. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/__init__.py +0 -0
  23. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/base.py +0 -0
  24. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -0
  25. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/error_handling.py +0 -0
  26. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/factory.py +0 -0
  27. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/logging.py +0 -0
  28. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/performance.py +0 -0
  29. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/protocol_middleware.py +0 -0
  30. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -0
  31. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/unified_security.py +0 -0
  32. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -0
  33. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/schemas.py +0 -0
  34. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/tool_integration.py +0 -0
  35. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/api/tools.py +0 -0
  36. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/__init__.py +0 -0
  37. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/auth_validation_command.py +0 -0
  38. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/base.py +0 -0
  39. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/builtin_commands.py +0 -0
  40. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/catalog_manager.py +0 -0
  41. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/cert_monitor_command.py +0 -0
  42. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/certificate_management_command.py +0 -0
  43. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/command_registry.py +0 -0
  44. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/config_command.py +0 -0
  45. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/dependency_container.py +0 -0
  46. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/dependency_manager.py +0 -0
  47. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/echo_command.py +0 -0
  48. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/health_command.py +0 -0
  49. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/help_command.py +0 -0
  50. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/hooks.py +0 -0
  51. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/key_management_command.py +0 -0
  52. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/load_command.py +0 -0
  53. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/plugins_command.py +0 -0
  54. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/protocol_management_command.py +0 -0
  55. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/proxy_registration_command.py +0 -0
  56. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/registration_status_command.py +0 -0
  57. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/reload_command.py +0 -0
  58. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/result.py +0 -0
  59. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/role_test_command.py +0 -0
  60. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/roles_management_command.py +0 -0
  61. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/security_command.py +0 -0
  62. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/settings_command.py +0 -0
  63. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/ssl_setup_command.py +0 -0
  64. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/token_management_command.py +0 -0
  65. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/transport_management_command.py +0 -0
  66. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/commands/unload_command.py +0 -0
  67. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/config.py +0 -0
  68. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/__init__.py +0 -0
  69. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/app_runner.py +0 -0
  70. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/auth_validator.py +0 -0
  71. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/certificate_utils.py +0 -0
  72. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/client.py +0 -0
  73. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/client_manager.py +0 -0
  74. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/client_security.py +0 -0
  75. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/config_converter.py +0 -0
  76. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/config_validator.py +0 -0
  77. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/crl_utils.py +0 -0
  78. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/errors.py +0 -0
  79. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/logging.py +0 -0
  80. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/mtls_asgi.py +0 -0
  81. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/mtls_asgi_app.py +0 -0
  82. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/mtls_proxy.py +0 -0
  83. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/protocol_manager.py +0 -0
  84. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/proxy_client.py +0 -0
  85. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/proxy_registration.py +0 -0
  86. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/role_utils.py +0 -0
  87. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/security_adapter.py +0 -0
  88. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/security_factory.py +0 -0
  89. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/security_integration.py +0 -0
  90. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/server_adapter.py +0 -0
  91. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/server_engine.py +0 -0
  92. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/settings.py +0 -0
  93. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/ssl_utils.py +0 -0
  94. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/transport_manager.py +0 -0
  95. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/core/unified_config_adapter.py +0 -0
  96. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/custom_openapi.py +0 -0
  97. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/__init__.py +0 -0
  98. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/basic_framework/__init__.py +0 -0
  99. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +0 -0
  100. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +0 -0
  101. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -0
  102. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/cert_manager_bugfix.py +0 -0
  103. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/check_config.py +0 -0
  104. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/commands/__init__.py +0 -0
  105. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/config_builder.py +0 -0
  106. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/config_cli.py +0 -0
  107. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/create_test_configs.py +0 -0
  108. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/debug_request_state.py +0 -0
  109. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/debug_role_chain.py +0 -0
  110. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/demo_client.py +0 -0
  111. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/__init__.py +0 -0
  112. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/commands/__init__.py +0 -0
  113. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -0
  114. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -0
  115. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -0
  116. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -0
  117. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -0
  118. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -0
  119. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/generate_config.py +0 -0
  120. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/proxy_registration_example.py +0 -0
  121. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/required_certificates.py +0 -0
  122. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/run_example.py +0 -0
  123. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/run_full_test_suite.py +0 -0
  124. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/run_proxy_server.py +0 -0
  125. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -0
  126. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/security_test_client.py +0 -0
  127. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/setup_test_environment.py +0 -0
  128. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/simple_protocol_test.py +0 -0
  129. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_chk_hostname_automated.py +0 -0
  130. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_config.py +0 -0
  131. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_config_builder.py +0 -0
  132. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_examples.py +0 -0
  133. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_framework_complete.py +0 -0
  134. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_mcp_server.py +0 -0
  135. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/test_protocol_examples.py +0 -0
  136. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/universal_client.py +0 -0
  137. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/examples/update_config_certificates.py +0 -0
  138. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/openapi.py +0 -0
  139. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/schemas/base_schema.json +0 -0
  140. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/schemas/openapi_schema.json +0 -0
  141. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/schemas/roles.json +0 -0
  142. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter/schemas/roles_schema.json +0 -0
  143. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/dependency_links.txt +0 -0
  144. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/entry_points.txt +0 -0
  145. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/not-zip-safe +0 -0
  146. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/requires.txt +0 -0
  147. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/mcp_proxy_adapter.egg-info/top_level.txt +0 -0
  148. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/setup.cfg +0 -0
  149. {mcp_proxy_adapter-6.7.2 → mcp_proxy_adapter-6.8.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-proxy-adapter
3
- Version: 6.7.2
3
+ Version: 6.8.0
4
4
  Summary: Powerful JSON-RPC microservices framework with built-in security, authentication, and proxy registration
5
5
  Home-page: https://github.com/maverikod/mcp-proxy-adapter
6
6
  Author: Vasiliy Zdanovskiy
@@ -156,6 +156,20 @@ def create_lifespan(config_path: Optional[str] = None):
156
156
  if not server_port:
157
157
  raise ValueError("server.port is required")
158
158
 
159
+ # Check port availability BEFORE starting registration manager
160
+ from mcp_proxy_adapter.core.utils import check_port_availability, handle_port_conflict
161
+
162
+ server_config = config.get("server", {})
163
+ server_host = server_config.get("host", "0.0.0.0")
164
+ server_port = server_config.get("port", 8000)
165
+
166
+ print(f"🔍 Checking external server port availability: {server_host}:{server_port}")
167
+ if not check_port_availability(server_host, server_port):
168
+ print(f"❌ CRITICAL: External server port {server_port} is occupied")
169
+ handle_port_conflict(server_host, server_port)
170
+ return # Exit the function immediately
171
+ print(f"✅ External server port {server_port} is available")
172
+
159
173
  # Determine registration URL using unified logic
160
174
  early_server_url = _determine_registration_url(config)
161
175
  try:
@@ -19,6 +19,11 @@ from mcp_proxy_adapter.config import config
19
19
  from mcp_proxy_adapter.commands.builtin_commands import (
20
20
  register_builtin_commands,
21
21
  )
22
+ from mcp_proxy_adapter.core.utils import (
23
+ check_port_availability,
24
+ handle_port_conflict,
25
+ find_port_for_internal_server,
26
+ )
22
27
 
23
28
  logger = get_logger("app_factory")
24
29
 
@@ -265,6 +270,7 @@ async def create_and_run_server(
265
270
  )
266
271
  print(f"🔌 Port: {server_port}")
267
272
 
273
+
268
274
  server_config = {
269
275
  "host": host,
270
276
  "port": server_port,
@@ -277,30 +283,6 @@ async def create_and_run_server(
277
283
  f"🔍 Debug: app_config keys: {list(app_config.keys()) if app_config else 'None'}"
278
284
  )
279
285
 
280
- # Check for SSL config in root section first (higher priority)
281
- if app_config and "ssl" in app_config:
282
- print(f"🔍 Debug: SSL config found in root: {app_config['ssl']}")
283
- print(
284
- f"🔍 Debug: SSL enabled: {app_config['ssl'].get('enabled', False)}"
285
- )
286
- if app_config["ssl"].get("enabled", False):
287
- ssl_config = app_config["ssl"]
288
- # Add SSL config directly to server_config for Hypercorn
289
- server_config["certfile"] = ssl_config.get("cert_file")
290
- server_config["keyfile"] = ssl_config.get("key_file")
291
- server_config["ca_certs"] = ssl_config.get(
292
- "ca_cert_file", ssl_config.get("ca_cert")
293
- )
294
- # Set verify_client based on verify_client setting
295
- verify_client = ssl_config.get("verify_client", False)
296
- server_config["verify_client"] = verify_client
297
- print(f"🔒 SSL enabled: {ssl_config.get('cert_file', 'N/A')}")
298
- print(
299
- f"🔒 SSL enabled: cert={ssl_config.get('cert_file')}, key={ssl_config.get('key_file')}"
300
- )
301
- print(
302
- f"🔒 Server config SSL: certfile={server_config.get('certfile')}, keyfile={server_config.get('keyfile')}, ca_certs={server_config.get('ca_certs')}, verify_mode={server_config.get('verify_mode')}"
303
- )
304
286
 
305
287
  # Check for SSL config in security section (fallback)
306
288
  if app_config and "security" in app_config:
@@ -331,28 +313,6 @@ async def create_and_run_server(
331
313
  print(
332
314
  f"🔒 Server config SSL: certfile={server_config.get('certfile')}, keyfile={server_config.get('keyfile')}, ca_certs={server_config.get('ca_certs')}, verify_mode={server_config.get('verify_mode')}"
333
315
  )
334
- print(f"🔍 Debug: SSL config found in root: {app_config['ssl']}")
335
- print(
336
- f"🔍 Debug: SSL enabled: {app_config['ssl'].get('enabled', False)}"
337
- )
338
- if app_config["ssl"].get("enabled", False):
339
- ssl_config = app_config["ssl"]
340
- # Add SSL config directly to server_config for Hypercorn
341
- server_config["certfile"] = ssl_config.get("cert_file")
342
- server_config["keyfile"] = ssl_config.get("key_file")
343
- server_config["ca_certs"] = ssl_config.get(
344
- "ca_cert_file", ssl_config.get("ca_cert")
345
- )
346
- # Set verify_client based on verify_client setting
347
- verify_client = ssl_config.get("verify_client", False)
348
- server_config["verify_client"] = verify_client
349
- print(f"🔒 SSL enabled: {ssl_config.get('cert_file', 'N/A')}")
350
- print(
351
- f"🔒 SSL enabled: cert={ssl_config.get('cert_file')}, key={ssl_config.get('key_file')}"
352
- )
353
- print(
354
- f"🔒 Server config SSL: certfile={server_config.get('certfile')}, keyfile={server_config.get('keyfile')}, ca_certs={server_config.get('ca_certs')}, verify_mode={server_config.get('verify_mode')}"
355
- )
356
316
 
357
317
  # 6. Start mTLS server if needed
358
318
  mtls_server = None
@@ -362,18 +322,21 @@ async def create_and_run_server(
362
322
  verify_client = ssl_config.get("verify_client", False)
363
323
 
364
324
  if verify_client:
365
- print("🔐 mTLS enabled - starting separate mTLS server...")
325
+ print("🔐 mTLS enabled - starting internal mTLS server...")
326
+ print(" External port: mTLS proxy (hypercorn)")
327
+ print(" Internal port: mTLS server (http.server)")
366
328
  from mcp_proxy_adapter.core.mtls_server import (
367
329
  start_mtls_server_thread,
368
330
  )
369
331
 
370
- # Start mTLS server in separate thread
332
+ # Start internal mTLS server in separate thread
333
+ # This server will find available port automatically if needed
371
334
  mtls_server = start_mtls_server_thread(app_config, main_app=app)
372
335
  if mtls_server:
373
- print(f"✅ mTLS server started on port {mtls_server.port}")
336
+ print(f"✅ Internal mTLS server started on port {mtls_server.port}")
374
337
  else:
375
338
  print(
376
- "⚠️ Failed to start mTLS server, continuing with regular HTTPS"
339
+ "⚠️ Failed to start internal mTLS server, continuing with regular HTTPS"
377
340
  )
378
341
  else:
379
342
  print("🔓 mTLS disabled - using regular HTTPS")
@@ -387,6 +350,8 @@ async def create_and_run_server(
387
350
  print(" Use Ctrl+C to stop the server")
388
351
  print("=" * 60)
389
352
 
353
+ # Port availability is already checked in api/app.py before registration manager starts
354
+
390
355
  # Use hypercorn directly
391
356
  import hypercorn.asyncio
392
357
  import hypercorn.config
@@ -428,13 +393,21 @@ async def create_and_run_server(
428
393
  if ssl_enabled:
429
394
  if verify_client:
430
395
  print(
431
- f"🔐 Starting HTTPS server with hypercorn (mTLS on separate port)..."
396
+ f"🔐 Starting external mTLS proxy with hypercorn (internal server on port {mtls_server.port if mtls_server else 'N/A'})..."
432
397
  )
433
398
  else:
434
399
  print(f"🔐 Starting HTTPS server with hypercorn...")
435
400
  else:
436
401
  print(f"🌐 Starting HTTP server with hypercorn...")
437
402
 
403
+ # Final port check before starting hypercorn
404
+ print(f"🔍 Final port check before starting hypercorn: {host}:{server_port}")
405
+ if not check_port_availability(host, server_port):
406
+ print(f"❌ CRITICAL: Port {server_port} is occupied during final check")
407
+ handle_port_conflict(host, server_port)
408
+ return # Exit immediately
409
+ print(f"✅ Final port check passed: {host}:{server_port}")
410
+
438
411
  # Run the server
439
412
  # hypercorn.asyncio.serve() should be run with asyncio.run(), not awaited
440
413
  # The function is designed to be the main entry point, not a coroutine to await
@@ -442,15 +415,28 @@ async def create_and_run_server(
442
415
 
443
416
  except KeyboardInterrupt:
444
417
  print("\n🛑 Server stopped by user")
445
- # Stop mTLS server if running
418
+ # Stop internal mTLS server if running
446
419
  if mtls_server:
447
- print("🛑 Stopping mTLS server...")
420
+ print("🛑 Stopping internal mTLS server...")
448
421
  mtls_server.stop()
422
+ except OSError as e:
423
+ if e.errno == 98: # Address already in use
424
+ print(f"\n❌ Port conflict detected: {e}")
425
+ handle_port_conflict(host, server_port)
426
+ else:
427
+ print(f"\n❌ Failed to start server: {e}")
428
+ # Stop mTLS server if running
429
+ if mtls_server:
430
+ print("🛑 Stopping mTLS server...")
431
+ mtls_server.stop()
432
+ import traceback
433
+ traceback.print_exc()
434
+ sys.exit(1)
449
435
  except Exception as e:
450
436
  print(f"\n❌ Failed to start server: {e}")
451
- # Stop mTLS server if running
437
+ # Stop internal mTLS server if running
452
438
  if mtls_server:
453
- print("🛑 Stopping mTLS server...")
439
+ print("🛑 Stopping internal mTLS server...")
454
440
  mtls_server.stop()
455
441
  import traceback
456
442
 
@@ -286,7 +286,11 @@ def start_mtls_server_thread(
286
286
  # Get server configuration
287
287
  server_config = config.get("server", {})
288
288
  host = server_config.get("host", "127.0.0.1")
289
- port = ssl_config.get("mtls_port", 8443) # Different port for mTLS
289
+ preferred_port = ssl_config.get("mtls_port", 8443) # Different port for mTLS
290
+
291
+ # For internal servers (mTLS), find available port if preferred is occupied
292
+ from mcp_proxy_adapter.core.utils import find_port_for_internal_server
293
+ port = find_port_for_internal_server(host, preferred_port)
290
294
 
291
295
  # Get certificate paths
292
296
  cert_file = ssl_config.get("cert_file", "certs/localhost_server.crt")
@@ -79,10 +79,12 @@ class SignalHandler:
79
79
  except Exception as e:
80
80
  logger.error(f"❌ Shutdown callback failed: {e}")
81
81
 
82
- # If this is SIGINT (Ctrl+C), we might want to exit immediately after a delay
83
- if signum == signal.SIGINT:
84
- logger.info("⏰ SIGINT received, will exit in 5 seconds if not stopped gracefully...")
85
- threading.Timer(5.0, self._force_exit).start()
82
+ # Force exit immediately to avoid server hang
83
+ logger.info("🔄 Force exiting to avoid server hang...")
84
+ import os
85
+ # Use os._exit for immediate termination
86
+ logger.warning("⚠️ Using os._exit for immediate termination...")
87
+ os._exit(0)
86
88
 
87
89
  def _force_exit(self):
88
90
  """Force exit if graceful shutdown takes too long."""
@@ -0,0 +1,282 @@
1
+ """
2
+ Module with utility functions for the microservice.
3
+ """
4
+
5
+ import hashlib
6
+ import json
7
+ import os
8
+ import socket
9
+ import sys
10
+ import time
11
+ import uuid
12
+ from datetime import datetime, timezone
13
+ from typing import Any, Dict, List, Optional, Tuple, Union
14
+
15
+ from mcp_proxy_adapter.core.logging import logger
16
+
17
+
18
+ def generate_id() -> str:
19
+ """
20
+ Generates a unique identifier.
21
+
22
+ Returns:
23
+ String with unique identifier.
24
+ """
25
+ return str(uuid.uuid4())
26
+
27
+
28
+ def get_timestamp() -> int:
29
+ """
30
+ Returns current timestamp in milliseconds.
31
+
32
+ Returns:
33
+ Integer - timestamp in milliseconds.
34
+ """
35
+ return int(time.time() * 1000)
36
+
37
+
38
+ def format_datetime(
39
+ dt: Optional[datetime] = None, format_str: str = "%Y-%m-%dT%H:%M:%S.%fZ"
40
+ ) -> str:
41
+ """
42
+ Formats date and time as string.
43
+
44
+ Args:
45
+ dt: Datetime object to format. If None, current time is used.
46
+ format_str: Format string for output.
47
+
48
+ Returns:
49
+ Formatted date/time string.
50
+ """
51
+ dt = dt or datetime.now(timezone.utc)
52
+ return dt.strftime(format_str)
53
+
54
+
55
+ def parse_datetime(dt_str: str, format_str: str = "%Y-%m-%dT%H:%M:%S.%fZ") -> datetime:
56
+ """
57
+ Parses date/time string into datetime object.
58
+
59
+ Args:
60
+ dt_str: Date/time string.
61
+ format_str: Date/time string format.
62
+
63
+ Returns:
64
+ Datetime object.
65
+ """
66
+ return datetime.strptime(dt_str, format_str)
67
+
68
+
69
+ def safe_json_loads(s: str, default: Any = None) -> Any:
70
+ """
71
+ Safe JSON string loading.
72
+
73
+ Args:
74
+ s: JSON string to load.
75
+ default: Default value on parsing error.
76
+
77
+ Returns:
78
+ Loaded object or default value on error.
79
+ """
80
+ try:
81
+ return json.loads(s)
82
+ except Exception as e:
83
+ logger.error(f"Error parsing JSON: {e}")
84
+ return default
85
+
86
+
87
+ def safe_json_dumps(obj: Any, default: str = "{}", indent: Optional[int] = None) -> str:
88
+ """
89
+ Safe object conversion to JSON string.
90
+
91
+ Args:
92
+ obj: Object to convert.
93
+ default: Default string on serialization error.
94
+ indent: Indentation for JSON formatting.
95
+
96
+ Returns:
97
+ JSON string or default string on error.
98
+ """
99
+ try:
100
+ return json.dumps(obj, ensure_ascii=False, indent=indent)
101
+ except Exception as e:
102
+ logger.error(f"Error serializing to JSON: {e}")
103
+ return default
104
+
105
+
106
+ def calculate_hash(data: Union[str, bytes], algorithm: str = "sha256") -> str:
107
+ """
108
+ Calculates hash for data.
109
+
110
+ Args:
111
+ data: Data to hash (string or bytes).
112
+ algorithm: Hashing algorithm (md5, sha1, sha256, etc.).
113
+
114
+ Returns:
115
+ String with hash in hexadecimal format.
116
+ """
117
+ if isinstance(data, str):
118
+ data = data.encode("utf-8")
119
+
120
+ hash_obj = hashlib.new(algorithm)
121
+ hash_obj.update(data)
122
+ return hash_obj.hexdigest()
123
+
124
+
125
+ def ensure_directory(path: str) -> bool:
126
+ """
127
+ Checks directory existence and creates it if necessary.
128
+
129
+ Args:
130
+ path: Path to directory.
131
+
132
+ Returns:
133
+ True if directory exists or was successfully created, otherwise False.
134
+ """
135
+ try:
136
+ if not os.path.exists(path):
137
+ os.makedirs(path, exist_ok=True)
138
+ return True
139
+ except Exception as e:
140
+ logger.error(f"Error creating directory {path}: {e}")
141
+ return False
142
+
143
+
144
+ def check_port_availability(host: str, port: int, timeout: float = 1.0) -> bool:
145
+ """
146
+ Checks if a port is available for binding.
147
+
148
+ Args:
149
+ host: Host address to check
150
+ port: Port number to check
151
+ timeout: Connection timeout in seconds
152
+
153
+ Returns:
154
+ True if port is available, False if port is in use
155
+ """
156
+ try:
157
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
158
+ sock.settimeout(timeout)
159
+ result = sock.connect_ex((host, port))
160
+ return result != 0 # True if connection failed (port is free)
161
+ except Exception as e:
162
+ logger.warning(f"Error checking port {port} on {host}: {e}")
163
+ return True # Assume port is available if check fails
164
+
165
+
166
+ def find_available_port(host: str, start_port: int, max_attempts: int = 100) -> Optional[int]:
167
+ """
168
+ Finds an available port starting from the specified port.
169
+
170
+ Args:
171
+ host: Host address to check
172
+ start_port: Starting port number
173
+ max_attempts: Maximum number of ports to check
174
+
175
+ Returns:
176
+ Available port number or None if no port found
177
+ """
178
+ for port in range(start_port, start_port + max_attempts):
179
+ if check_port_availability(host, port):
180
+ return port
181
+ return None
182
+
183
+
184
+ def get_port_usage_info(port: int) -> str:
185
+ """
186
+ Gets information about what process is using a port.
187
+
188
+ Args:
189
+ port: Port number to check
190
+
191
+ Returns:
192
+ String with port usage information
193
+ """
194
+ try:
195
+ import subprocess
196
+ result = subprocess.run(
197
+ ["lsof", "-i", f":{port}"],
198
+ capture_output=True,
199
+ text=True,
200
+ timeout=5
201
+ )
202
+ if result.returncode == 0 and result.stdout.strip():
203
+ return f"Port {port} is used by:\n{result.stdout.strip()}"
204
+ else:
205
+ return f"Port {port} appears to be in use but process info unavailable"
206
+ except Exception as e:
207
+ return f"Port {port} is in use (unable to get process info: {e})"
208
+
209
+
210
+ def handle_port_conflict(host: str, port: int) -> None:
211
+ """
212
+ Handles port conflict with user-friendly error message and suggestions.
213
+ This is for MAIN server port conflicts - application must exit.
214
+
215
+ Args:
216
+ host: Host address
217
+ port: Port number that's in conflict
218
+ """
219
+ print(f"❌ ERROR: Port {port} is already in use on {host}")
220
+ print(f"💡 Suggestions:")
221
+ print(f" 1. Choose a different port: --port <different_port>")
222
+ print(f" 2. Stop the conflicting service")
223
+ print(f" 3. Check what's using the port:")
224
+ print(f" lsof -i :{port}")
225
+ print(f" netstat -tulpn | grep :{port}")
226
+
227
+ # Try to get more detailed info about port usage
228
+ usage_info = get_port_usage_info(port)
229
+ print(f"🔍 Port usage details:")
230
+ print(f" {usage_info}")
231
+
232
+ # Try to find an alternative port
233
+ alt_port = find_available_port(host, port + 1, 10)
234
+ if alt_port:
235
+ print(f"💡 Alternative port suggestion: {alt_port}")
236
+ print(f" Try: --port {alt_port}")
237
+ else:
238
+ print(f"💡 Try ports in range {port + 1}-{port + 20}")
239
+
240
+ print(f"🛑 Application cannot start due to port conflict")
241
+ sys.exit(1)
242
+
243
+
244
+ def find_port_for_internal_server(host: str, preferred_port: int) -> int:
245
+ """
246
+ Finds an available port for internal server (mTLS, etc.).
247
+ If preferred port is occupied, finds any available port.
248
+
249
+ Args:
250
+ host: Host address
251
+ preferred_port: Preferred port number
252
+
253
+ Returns:
254
+ Available port number
255
+ """
256
+ # First try the preferred port
257
+ if check_port_availability(host, preferred_port):
258
+ print(f"✅ Internal server port {preferred_port} is available")
259
+ return preferred_port
260
+
261
+ # If preferred port is occupied, find any available port
262
+ print(f"⚠️ Internal server preferred port {preferred_port} is occupied, searching for alternative...")
263
+
264
+ alt_port = find_available_port(host, preferred_port + 1, 50)
265
+ if alt_port:
266
+ print(f"✅ Found alternative port for internal server: {alt_port}")
267
+ return alt_port
268
+
269
+ # If no port found in range, try from 9000
270
+ alt_port = find_available_port(host, 9000, 100)
271
+ if alt_port:
272
+ print(f"✅ Found alternative port for internal server: {alt_port}")
273
+ return alt_port
274
+
275
+ # Last resort - try from 10000
276
+ alt_port = find_available_port(host, 10000, 100)
277
+ if alt_port:
278
+ print(f"✅ Found alternative port for internal server: {alt_port}")
279
+ return alt_port
280
+
281
+ # If still no port found, raise error
282
+ raise RuntimeError(f"Unable to find available port for internal server on {host}")
@@ -25,27 +25,26 @@ def main():
25
25
  parser.add_argument("--port", type=int, help="Server port")
26
26
  parser.add_argument("--debug", action="store_true", help="Enable debug mode")
27
27
  args = parser.parse_args()
28
- # Override configuration if specified
29
- config_overrides = {}
28
+ print(f"🚀 Starting Basic Framework Example")
29
+ print(f"📋 Configuration: {args.config}")
30
30
  if args.host:
31
- config_overrides["host"] = args.host
31
+ print(f"🌐 Host override: {args.host}")
32
32
  if args.port:
33
- config_overrides["port"] = args.port
33
+ print(f"🔌 Port override: {args.port}")
34
34
  if args.debug:
35
- config_overrides["debug"] = True
36
- print(f"🚀 Starting Basic Framework Example")
37
- print(f"📋 Configuration: {args.config}")
35
+ print(f"🔧 Debug mode: enabled")
38
36
  print("=" * 50)
39
- # Use the factory method to create and run the server
37
+
38
+ # Note: Host and port overrides should be handled in configuration file
39
+ # or by modifying the configuration before passing to create_and_run_server
40
40
  import asyncio
41
41
  asyncio.run(create_and_run_server(
42
42
  config_path=args.config,
43
43
  title="Basic Framework Example",
44
44
  description="Basic MCP Proxy Adapter with minimal configuration",
45
45
  version="1.0.0",
46
- host=config_overrides.get("host"),
47
- port=config_overrides.get("port"),
48
- debug=config_overrides.get("debug", False),
46
+ host=args.host or "0.0.0.0",
47
+ log_level="debug" if args.debug else "info"
49
48
  ))
50
49
 
51
50
 
@@ -93,74 +93,24 @@ class FullApplication:
93
93
  self.logger.info("✅ Application created successfully")
94
94
 
95
95
  def run(self, host: str = None, port: int = None, debug: bool = False):
96
- """Run the application using the factory method."""
97
- # Override configuration if specified
98
- config_overrides = {}
99
- if host:
100
- config_overrides["host"] = host
101
- if port:
102
- config_overrides["port"] = port
103
- if debug:
104
- config_overrides["debug"] = True
96
+ """Run the application using the factory method with port checking."""
105
97
  print(f"🚀 Starting Full Application Example")
106
98
  print(f"📋 Configuration: {self.config_path}")
107
99
  print(
108
100
  f"🔧 Features: Built-in commands, Custom commands, Dynamic commands, Hooks, Proxy endpoints"
109
101
  )
110
102
  print("=" * 60)
111
- # Create application with configuration
112
- self.create_application()
113
- # Get server configuration
114
- server_host = self.config.get("server.host", "0.0.0.0")
115
- server_port = self.config.get("server.port", 8000)
116
- server_debug = self.config.get("server.debug", False)
117
- # Get SSL configuration
118
- ssl_enabled = self.config.get("ssl.enabled", False)
119
- ssl_cert_file = self.config.get("ssl.cert_file")
120
- ssl_key_file = self.config.get("ssl.key_file")
121
- ssl_ca_cert = self.config.get("ssl.ca_cert")
122
- verify_client = self.config.get("ssl.verify_client", False)
123
- print(f"🌐 Server: {server_host}:{server_port}")
124
- print(f"🔧 Debug: {server_debug}")
125
- if ssl_enabled:
126
- print(f"🔐 SSL: Enabled")
127
- print(f" Certificate: {ssl_cert_file}")
128
- print(f" Key: {ssl_key_file}")
129
- if ssl_ca_cert:
130
- print(f" CA: {ssl_ca_cert}")
131
- print(f" Client verification: {verify_client}")
132
- print("=" * 60)
133
- # Use hypercorn directly to run the application with proxy endpoints
134
- try:
135
- import hypercorn.asyncio
136
- import hypercorn.config
137
- import asyncio
138
-
139
- # Configure hypercorn
140
- config_hypercorn = hypercorn.config.Config()
141
- config_hypercorn.bind = [f"{server_host}:{server_port}"]
142
- config_hypercorn.loglevel = "debug" if server_debug else "info"
143
- if ssl_enabled and ssl_cert_file and ssl_key_file:
144
- config_hypercorn.certfile = ssl_cert_file
145
- config_hypercorn.keyfile = ssl_key_file
146
- if ssl_ca_cert:
147
- config_hypercorn.ca_certs = ssl_ca_cert
148
- if verify_client:
149
- import ssl
150
-
151
- config_hypercorn.verify_mode = ssl.CERT_REQUIRED
152
- print(f"🔐 Starting HTTPS server with hypercorn...")
153
- else:
154
- print(f"🌐 Starting HTTP server with hypercorn...")
155
- # Run the server
156
- asyncio.run(hypercorn.asyncio.serve(self.app, config_hypercorn))
157
- except ImportError:
158
- print("❌ hypercorn not installed. Installing...")
159
- import subprocess
160
-
161
- subprocess.run([sys.executable, "-m", "pip", "install", "hypercorn"])
162
- print("✅ hypercorn installed. Please restart the application.")
163
- return
103
+
104
+ # Use the factory method to create and run the server with port checking
105
+ import asyncio
106
+ asyncio.run(create_and_run_server(
107
+ config_path=self.config_path,
108
+ title="Full Application Example",
109
+ description="Complete MCP Proxy Adapter with all features",
110
+ version="1.0.0",
111
+ host=host or "0.0.0.0",
112
+ log_level="debug" if debug else "info"
113
+ ))
164
114
 
165
115
 
166
116
  def main():