mcp-proxy-adapter 6.6.1__tar.gz → 6.6.4__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.
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/app.py +61 -55
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/command_registry.py +27 -13
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/config.py +1 -8
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/proxy_registration.py +80 -7
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/server_adapter.py +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/check_config.py +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/config_builder.py +13 -19
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_bugfix.py → mcp_proxy_adapter-6.6.4/mcp_proxy_adapter/examples/generate_certificates.py +11 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/generate_config.py +3 -3
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/run_full_test_suite.py +3 -3
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/security_test_client.py +6 -5
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/test_chk_hostname_automated.py +7 -10
- mcp_proxy_adapter-6.6.4/mcp_proxy_adapter/examples/test_framework_complete.py +269 -0
- mcp_proxy_adapter-6.6.4/mcp_proxy_adapter/examples/test_mcp_server.py +188 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/main.py +19 -18
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/SOURCES.txt +6 -14
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/pyproject.toml +1 -1
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/config_builder_simple.py +0 -271
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_all_certificates.py +0 -487
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_cli.py +0 -406
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_fixed.py +0 -313
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_framework.py +0 -366
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_openssl.py +0 -391
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/README.md +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/__main__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/handlers.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/base.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/error_handling.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/factory.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/logging.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/performance.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/protocol_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/unified_security.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/schemas.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/tool_integration.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/api/tools.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/auth_validation_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/base.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/builtin_commands.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/catalog_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/cert_monitor_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/certificate_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/config_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/dependency_container.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/dependency_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/echo_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/health_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/help_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/hooks.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/key_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/load_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/plugins_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/protocol_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/proxy_registration_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/reload_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/result.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/role_test_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/roles_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/security_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/settings_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/ssl_setup_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/token_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/transport_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/unload_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/app_factory.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/app_runner.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/auth_validator.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/certificate_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/client_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/client_security.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/config_converter.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/config_validator.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/crl_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/errors.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/logging.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/mtls_asgi.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/mtls_asgi_app.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/mtls_server.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/protocol_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/proxy_client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/role_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/security_adapter.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/security_factory.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/security_integration.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/server_engine.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/settings.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/ssl_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/transport_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/unified_config_adapter.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/custom_openapi.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/basic_framework/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/basic_framework/main.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/cert_manager_bugfix.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/config_cli.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/create_test_configs.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/debug_request_state.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/debug_role_chain.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/demo_client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/main.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/proxy_registration_example.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/required_certificates.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/run_example.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/run_proxy_server.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/setup_test_environment.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/simple_protocol_test.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/test_config.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/test_config_builder.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/test_examples.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/test_protocol_examples.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/universal_client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/update_config_certificates.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/openapi.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/schemas/base_schema.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/schemas/openapi_schema.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/schemas/roles.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/schemas/roles_schema.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/dependency_links.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/not-zip-safe +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/requires.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter.egg-info/top_level.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/setup.cfg +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-proxy-adapter
|
3
|
-
Version: 6.6.
|
3
|
+
Version: 6.6.4
|
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
|
@@ -65,11 +65,8 @@ def create_lifespan(config_path: Optional[str] = None):
|
|
65
65
|
initialize_proxy_registration,
|
66
66
|
)
|
67
67
|
|
68
|
-
#
|
69
|
-
|
70
|
-
initialize_proxy_registration(config.get_all())
|
71
|
-
except Exception as e:
|
72
|
-
logger.error(f"Failed to initialize proxy registration: {e}")
|
68
|
+
# Proxy registration manager will be initialized in registry.reload_system()
|
69
|
+
# after all commands are loaded to ensure complete command schema
|
73
70
|
|
74
71
|
# Compute server_url EARLY and inject into registration manager so
|
75
72
|
# that reload_system (which may perform registration) uses the correct
|
@@ -88,11 +85,11 @@ def create_lifespan(config_path: Optional[str] = None):
|
|
88
85
|
public_host = reg_cfg.get("public_host")
|
89
86
|
public_port = reg_cfg.get("public_port")
|
90
87
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
protocol = "https" if
|
88
|
+
# Check SSL configuration from new structure
|
89
|
+
protocol = config.get("server.protocol", "http")
|
90
|
+
verify_client = config.get("transport.verify_client", False)
|
91
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
92
|
+
protocol = "https" if ssl_enabled else "http"
|
96
93
|
|
97
94
|
import os
|
98
95
|
docker_host_addr = os.getenv("DOCKER_HOST_ADDR", "172.17.0.1")
|
@@ -124,11 +121,7 @@ def create_lifespan(config_path: Optional[str] = None):
|
|
124
121
|
)
|
125
122
|
logger.info(f"System initialization result: {init_result}")
|
126
123
|
|
127
|
-
#
|
128
|
-
try:
|
129
|
-
initialize_proxy_registration(config.get_all())
|
130
|
-
except Exception as e:
|
131
|
-
logger.error(f"Failed to initialize proxy registration: {e}")
|
124
|
+
# Proxy registration manager is already initialized in registry.reload_system()
|
132
125
|
|
133
126
|
# Recompute registration URL AFTER config reload using final config
|
134
127
|
try:
|
@@ -141,11 +134,11 @@ def create_lifespan(config_path: Optional[str] = None):
|
|
141
134
|
public_host = reg_cfg.get("public_host")
|
142
135
|
public_port = reg_cfg.get("public_port")
|
143
136
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
protocol = "https" if
|
137
|
+
# Determine protocol using the new configuration structure
|
138
|
+
protocol_cfg = final_config.get("server", {}).get("protocol", "http")
|
139
|
+
verify_client_cfg = final_config.get("transport", {}).get("verify_client", False)
|
140
|
+
ssl_enabled_final = protocol_cfg in ["https", "mtls"] or verify_client_cfg
|
141
|
+
protocol = "https" if ssl_enabled_final else "http"
|
149
142
|
|
150
143
|
import os
|
151
144
|
docker_host_addr = os.getenv("DOCKER_HOST_ADDR", "172.17.0.1")
|
@@ -184,19 +177,26 @@ def create_lifespan(config_path: Optional[str] = None):
|
|
184
177
|
logger.error(f"Failed to recompute registration URL: {e}")
|
185
178
|
server_url = early_server_url
|
186
179
|
|
187
|
-
#
|
188
|
-
|
180
|
+
# Proxy registration is now handled in registry.reload_system()
|
181
|
+
# after all commands are loaded, ensuring complete command schema
|
182
|
+
logger.info("ℹ️ Proxy registration will be handled after command loading completes")
|
183
|
+
|
184
|
+
# Add delayed registration task to allow server to fully start
|
185
|
+
async def delayed_registration():
|
186
|
+
"""Delayed registration to ensure server is fully started."""
|
187
|
+
await asyncio.sleep(2) # Wait for server to start listening
|
188
|
+
logger.info("🔄 Attempting delayed proxy registration after server startup")
|
189
189
|
try:
|
190
|
-
|
190
|
+
from mcp_proxy_adapter.core.proxy_registration import register_with_proxy
|
191
191
|
success = await register_with_proxy(server_url)
|
192
192
|
if success:
|
193
|
-
logger.info("✅
|
193
|
+
logger.info("✅ Delayed proxy registration successful")
|
194
194
|
else:
|
195
|
-
logger.
|
195
|
+
logger.warning("⚠️ Delayed proxy registration failed")
|
196
196
|
except Exception as e:
|
197
|
-
logger.error(f"
|
198
|
-
|
199
|
-
asyncio.create_task(
|
197
|
+
logger.error(f"❌ Delayed proxy registration error: {e}")
|
198
|
+
|
199
|
+
asyncio.create_task(delayed_registration())
|
200
200
|
|
201
201
|
yield # Application is running
|
202
202
|
|
@@ -227,20 +227,30 @@ def create_ssl_context(
|
|
227
227
|
"""
|
228
228
|
current_config = app_config if app_config is not None else config.get_all()
|
229
229
|
|
230
|
-
#
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# Fallback to legacy SSL config
|
235
|
-
if not ssl_config.get("enabled", False):
|
236
|
-
ssl_config = current_config.get("ssl", {})
|
230
|
+
# Check SSL configuration from new structure
|
231
|
+
protocol = current_config.get("server", {}).get("protocol", "http")
|
232
|
+
verify_client = current_config.get("transport", {}).get("verify_client", False)
|
233
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
237
234
|
|
238
|
-
if not
|
235
|
+
if not ssl_enabled:
|
239
236
|
logger.info("SSL is disabled in configuration")
|
240
237
|
return None
|
241
238
|
|
242
|
-
|
243
|
-
|
239
|
+
# Get certificate paths from configuration
|
240
|
+
cert_file = current_config.get("transport", {}).get("cert_file")
|
241
|
+
key_file = current_config.get("transport", {}).get("key_file")
|
242
|
+
ca_cert = current_config.get("transport", {}).get("ca_cert")
|
243
|
+
|
244
|
+
# Convert relative paths to absolute paths
|
245
|
+
if cert_file and not Path(cert_file).is_absolute():
|
246
|
+
project_root = Path(__file__).parent.parent.parent
|
247
|
+
cert_file = str(project_root / cert_file)
|
248
|
+
if key_file and not Path(key_file).is_absolute():
|
249
|
+
project_root = Path(__file__).parent.parent.parent
|
250
|
+
key_file = str(project_root / key_file)
|
251
|
+
if ca_cert and not Path(ca_cert).is_absolute():
|
252
|
+
project_root = Path(__file__).parent.parent.parent
|
253
|
+
ca_cert = str(project_root / ca_cert)
|
244
254
|
|
245
255
|
if not cert_file or not key_file:
|
246
256
|
logger.warning("SSL enabled but certificate or key file not specified")
|
@@ -251,15 +261,15 @@ def create_ssl_context(
|
|
251
261
|
ssl_context = SSLUtils.create_ssl_context(
|
252
262
|
cert_file=cert_file,
|
253
263
|
key_file=key_file,
|
254
|
-
ca_cert=
|
255
|
-
verify_client=
|
256
|
-
cipher_suites=
|
257
|
-
min_tls_version=
|
258
|
-
max_tls_version=
|
264
|
+
ca_cert=ca_cert,
|
265
|
+
verify_client=current_config.get("transport", {}).get("verify_client", False),
|
266
|
+
cipher_suites=[],
|
267
|
+
min_tls_version="1.2",
|
268
|
+
max_tls_version="1.3",
|
259
269
|
)
|
260
270
|
|
261
271
|
logger.info(
|
262
|
-
f"SSL context created successfully for mode:
|
272
|
+
f"SSL context created successfully for mode: https_only"
|
263
273
|
)
|
264
274
|
return ssl_context
|
265
275
|
|
@@ -308,17 +318,13 @@ def create_app(
|
|
308
318
|
print(
|
309
319
|
f"🔍 Debug: create_app received app_config keys: {list(app_config.keys())}"
|
310
320
|
)
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
)
|
319
|
-
print(
|
320
|
-
f"🔍 Debug: create_app SSL config: key_file={ssl_config.get('key_file')}"
|
321
|
-
)
|
321
|
+
# Debug SSL configuration
|
322
|
+
protocol = app_config.get("server", {}).get("protocol", "http")
|
323
|
+
verify_client = app_config.get("transport", {}).get("verify_client", False)
|
324
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
325
|
+
print(f"🔍 Debug: create_app SSL config: enabled={ssl_enabled}")
|
326
|
+
print(f"🔍 Debug: create_app protocol: {protocol}")
|
327
|
+
print(f"🔍 Debug: create_app verify_client: {verify_client}")
|
322
328
|
else:
|
323
329
|
print(f"🔍 Debug: create_app received app_config type: {type(app_config)}")
|
324
330
|
else:
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/commands/command_registry.py
RENAMED
@@ -786,23 +786,37 @@ class CommandRegistry:
|
|
786
786
|
# Initialize proxy registration manager with current config
|
787
787
|
initialize_proxy_registration(config.get_all())
|
788
788
|
|
789
|
-
# Get server configuration
|
789
|
+
# Get server configuration with proper URL resolution logic
|
790
790
|
server_config = config.get("server", {})
|
791
791
|
server_host = server_config.get("host", "0.0.0.0")
|
792
792
|
server_port = server_config.get("port", 8000)
|
793
793
|
|
794
|
-
#
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
794
|
+
# Get registration configuration for public host/port overrides
|
795
|
+
# First check server config, then registration config
|
796
|
+
public_host = config.get("server.public_host")
|
797
|
+
public_port = config.get("server.public_port")
|
798
|
+
|
799
|
+
# Fallback to registration config if not found in server
|
800
|
+
if not public_host or not public_port:
|
801
|
+
reg_cfg = config.get("registration", config.get("proxy_registration", {}))
|
802
|
+
public_host = public_host or reg_cfg.get("public_host")
|
803
|
+
public_port = public_port or reg_cfg.get("public_port")
|
804
|
+
|
805
|
+
# Determine protocol based on new configuration structure
|
806
|
+
protocol = config.get("server.protocol", "http")
|
807
|
+
verify_client = config.get("transport.verify_client", False)
|
808
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
809
|
+
protocol = "https" if ssl_enabled else "http"
|
810
|
+
|
811
|
+
# Resolve host and port (same logic as in app.py)
|
812
|
+
import os
|
813
|
+
docker_host_addr = os.getenv("DOCKER_HOST_ADDR", "172.17.0.1")
|
814
|
+
resolved_host = public_host or (docker_host_addr if server_host == "0.0.0.0" else server_host)
|
815
|
+
resolved_port = public_port or server_port
|
816
|
+
|
817
|
+
server_url = f"{protocol}://{resolved_host}:{resolved_port}"
|
818
|
+
|
819
|
+
logger.info(f"🔍 Proxy registration URL resolved: {server_url}")
|
806
820
|
|
807
821
|
# Attempt proxy registration
|
808
822
|
proxy_registration_success = await register_with_proxy(server_url)
|
@@ -84,15 +84,8 @@ class Config:
|
|
84
84
|
"transport": {
|
85
85
|
"type": "http",
|
86
86
|
"port": None,
|
87
|
-
"ssl": {
|
88
|
-
"enabled": False,
|
89
|
-
"cert_file": None,
|
90
|
-
"key_file": None,
|
91
|
-
"ca_cert": None,
|
92
87
|
"verify_client": False,
|
93
|
-
|
94
|
-
"chk_hostname": False, # Default to False when SSL is disabled
|
95
|
-
},
|
88
|
+
"chk_hostname": False, # Default to False for HTTP
|
96
89
|
},
|
97
90
|
"proxy_registration": {
|
98
91
|
"enabled": False,
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/proxy_registration.py
RENAMED
@@ -13,6 +13,7 @@ email: vasilyvz@gmail.com
|
|
13
13
|
import asyncio
|
14
14
|
import time
|
15
15
|
import ssl
|
16
|
+
import traceback
|
16
17
|
from typing import Dict, Any, Optional, Tuple
|
17
18
|
from pathlib import Path
|
18
19
|
from urllib.parse import urljoin
|
@@ -248,10 +249,15 @@ class ProxyRegistrationManager:
|
|
248
249
|
"""
|
249
250
|
logger.debug("_create_ssl_context called")
|
250
251
|
|
251
|
-
#
|
252
|
-
|
253
|
-
|
254
|
-
|
252
|
+
# Decide SSL strictly by proxy URL scheme: use SSL only for https proxy URLs
|
253
|
+
try:
|
254
|
+
from urllib.parse import urlparse as _urlparse
|
255
|
+
scheme = _urlparse(self.proxy_url).scheme if self.proxy_url else "http"
|
256
|
+
if scheme.lower() != "https":
|
257
|
+
logger.debug("Proxy URL is HTTP, skipping SSL context creation for registration")
|
258
|
+
return None
|
259
|
+
except Exception:
|
260
|
+
logger.debug("Failed to parse proxy_url, assuming HTTP and skipping SSL context")
|
255
261
|
return None
|
256
262
|
|
257
263
|
if not self.client_security:
|
@@ -440,7 +446,11 @@ class ProxyRegistrationManager:
|
|
440
446
|
|
441
447
|
if success:
|
442
448
|
self.registered = True
|
443
|
-
|
449
|
+
# Safely extract server_key from result
|
450
|
+
if isinstance(result, dict):
|
451
|
+
self.server_key = result.get("server_key")
|
452
|
+
else:
|
453
|
+
self.server_key = None
|
444
454
|
logger.info(
|
445
455
|
f"✅ Successfully registered with proxy. Server key: {self.server_key}"
|
446
456
|
)
|
@@ -455,8 +465,65 @@ class ProxyRegistrationManager:
|
|
455
465
|
else:
|
456
466
|
# Be robust if result is not a dict
|
457
467
|
error_msg = None
|
468
|
+
logger.error(f"DEBUG: result type = {type(result)}, result = {result}")
|
458
469
|
if isinstance(result, dict):
|
459
|
-
|
470
|
+
logger.error(f"DEBUG: result is dict, getting error field")
|
471
|
+
error_field = result.get("error", {})
|
472
|
+
logger.error(f"DEBUG: error_field type = {type(error_field)}, error_field = {error_field}")
|
473
|
+
if isinstance(error_field, dict):
|
474
|
+
error_msg = error_field.get("message", "Unknown error")
|
475
|
+
elif isinstance(error_field, str):
|
476
|
+
error_msg = error_field
|
477
|
+
else:
|
478
|
+
error_msg = str(error_field)
|
479
|
+
|
480
|
+
# Auto-recovery: already registered case → force unregistration then retry once
|
481
|
+
error_code = result.get("error_code") or (result.get("error", {}).get("code") if isinstance(result.get("error"), dict) else None)
|
482
|
+
already_registered = False
|
483
|
+
existing_server_key = None
|
484
|
+
# Prefer structured detail if provided
|
485
|
+
if isinstance(result.get("details"), dict):
|
486
|
+
existing_server_key = result.get("details", {}).get("existing_server_key")
|
487
|
+
# Fallback: parse from error message text
|
488
|
+
if not existing_server_key and isinstance(error_msg, str) and "already registered as" in error_msg:
|
489
|
+
try:
|
490
|
+
# Expecting: "... already registered as <server_id>_<copy_number>"
|
491
|
+
tail = error_msg.split("already registered as", 1)[1].strip()
|
492
|
+
existing_server_key = tail.split()[0]
|
493
|
+
except Exception:
|
494
|
+
existing_server_key = None
|
495
|
+
|
496
|
+
if (error_code in ("DUPLICATE_SERVER_URL", "REGISTRATION_ERROR") or already_registered) and existing_server_key:
|
497
|
+
try:
|
498
|
+
logger.info(f"Attempting auto-unregistration of existing instance: {existing_server_key}")
|
499
|
+
# Build unregistration payload using parsed server_key
|
500
|
+
try:
|
501
|
+
copy_number = int(existing_server_key.split("_")[-1])
|
502
|
+
except Exception:
|
503
|
+
copy_number = 1
|
504
|
+
unregistration_data = {"server_id": self.server_id, "copy_number": copy_number}
|
505
|
+
# Reuse secure unregistration request directly
|
506
|
+
unreg_success, _unreg_result = await self._make_secure_unregistration_request(unregistration_data)
|
507
|
+
if unreg_success:
|
508
|
+
logger.info("Auto-unregistration succeeded, retrying registration once...")
|
509
|
+
# Retry registration once immediately
|
510
|
+
retry_success, retry_result = await self._make_secure_registration_request(registration_data)
|
511
|
+
if retry_success:
|
512
|
+
self.registered = True
|
513
|
+
if isinstance(retry_result, dict):
|
514
|
+
self.server_key = retry_result.get("server_key")
|
515
|
+
else:
|
516
|
+
self.server_key = None
|
517
|
+
logger.info(f"✅ Successfully registered after auto-unregistration. Server key: {self.server_key}")
|
518
|
+
if self.registration_config.get("heartbeat", {}).get("enabled", True):
|
519
|
+
await self._start_heartbeat()
|
520
|
+
return True
|
521
|
+
else:
|
522
|
+
logger.warning(f"Retry registration failed after auto-unregistration: {retry_result}")
|
523
|
+
else:
|
524
|
+
logger.warning(f"Auto-unregistration failed: {_unreg_result}")
|
525
|
+
except Exception as _auto_e:
|
526
|
+
logger.warning(f"Auto-unregistration/registration flow error: {_auto_e}")
|
460
527
|
else:
|
461
528
|
error_msg = str(result)
|
462
529
|
logger.warning(
|
@@ -467,6 +534,7 @@ class ProxyRegistrationManager:
|
|
467
534
|
logger.error(
|
468
535
|
f"❌ Registration attempt {attempt + 1} failed with exception: {e}"
|
469
536
|
)
|
537
|
+
logger.error(f"Full traceback: {traceback.format_exc()}")
|
470
538
|
|
471
539
|
logger.error(
|
472
540
|
f"❌ Failed to register with proxy after {self.retry_attempts} attempts"
|
@@ -562,8 +630,10 @@ class ProxyRegistrationManager:
|
|
562
630
|
) as response:
|
563
631
|
try:
|
564
632
|
result = await response.json()
|
565
|
-
|
633
|
+
logger.debug(f"Response JSON parsed successfully: {type(result)} - {result}")
|
634
|
+
except Exception as e:
|
566
635
|
text_body = await response.text()
|
636
|
+
logger.debug(f"JSON parsing failed: {e}, text_body: {text_body}")
|
567
637
|
result = {"success": False, "error": {"code": "NON_JSON_RESPONSE", "message": text_body}}
|
568
638
|
|
569
639
|
# Validate response headers if security framework available
|
@@ -604,6 +674,9 @@ class ProxyRegistrationManager:
|
|
604
674
|
logger.warning(
|
605
675
|
f"Registration failed with HTTP status: {response.status}"
|
606
676
|
)
|
677
|
+
# Ensure result is a dict for consistent error handling
|
678
|
+
if isinstance(result, str):
|
679
|
+
result = {"success": False, "error": {"code": "HTTP_ERROR", "message": result}}
|
607
680
|
return False, result
|
608
681
|
finally:
|
609
682
|
if connector:
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/core/server_adapter.py
RENAMED
@@ -65,7 +65,7 @@ class ServerConfigAdapter:
|
|
65
65
|
|
66
66
|
# Map verification mode
|
67
67
|
if ssl_config.get("verify_client", False):
|
68
|
-
hypercorn_ssl["verify_mode"] =
|
68
|
+
hypercorn_ssl["verify_mode"] = 2 # ssl.CERT_REQUIRED
|
69
69
|
|
70
70
|
# Map hostname checking
|
71
71
|
if "chk_hostname" in ssl_config:
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/check_config.py
RENAMED
@@ -15,7 +15,7 @@ from pathlib import Path
|
|
15
15
|
from typing import Dict, Any, List, Optional
|
16
16
|
|
17
17
|
# Add the project root to the path
|
18
|
-
sys.path.insert(0, str(Path(__file__).parent))
|
18
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
19
19
|
|
20
20
|
from mcp_proxy_adapter.config import Config
|
21
21
|
from mcp_proxy_adapter.examples.config_builder import ConfigBuilder, Protocol, AuthMethod
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/config_builder.py
RENAMED
@@ -76,16 +76,9 @@ class ConfigBuilder:
|
|
76
76
|
},
|
77
77
|
"transport": {
|
78
78
|
"type": "http",
|
79
|
-
|
80
|
-
"
|
81
|
-
|
82
|
-
"cert_file": None,
|
83
|
-
"key_file": None,
|
84
|
-
"ca_cert": None,
|
85
|
-
"verify_client": False,
|
86
|
-
"client_cert_required": False,
|
87
|
-
"chk_hostname": False,
|
88
|
-
},
|
79
|
+
"port": None,
|
80
|
+
"verify_client": False,
|
81
|
+
"chk_hostname": False
|
89
82
|
}
|
90
83
|
}
|
91
84
|
|
@@ -94,18 +87,19 @@ class ConfigBuilder:
|
|
94
87
|
self.config["server"]["protocol"] = protocol.value
|
95
88
|
|
96
89
|
if protocol == Protocol.HTTP:
|
97
|
-
# HTTP - no SSL
|
98
|
-
|
90
|
+
# HTTP - no SSL, no client verification
|
91
|
+
self.config["transport"]["verify_client"] = False
|
92
|
+
self.config["transport"]["chk_hostname"] = False
|
99
93
|
|
100
94
|
elif protocol == Protocol.HTTPS:
|
101
|
-
# HTTPS -
|
102
|
-
|
103
|
-
|
95
|
+
# HTTPS - SSL enabled, no client verification
|
96
|
+
self.config["transport"]["verify_client"] = False
|
97
|
+
self.config["transport"]["chk_hostname"] = True
|
104
98
|
|
105
99
|
elif protocol == Protocol.MTLS:
|
106
|
-
# mTLS -
|
107
|
-
|
108
|
-
|
100
|
+
# mTLS - SSL enabled, client verification required
|
101
|
+
self.config["transport"]["verify_client"] = True
|
102
|
+
self.config["transport"]["chk_hostname"] = True
|
109
103
|
|
110
104
|
return self
|
111
105
|
|
@@ -237,7 +231,7 @@ class ConfigFactory:
|
|
237
231
|
.set_auth(AuthMethod.TOKEN)
|
238
232
|
.set_server(port=port)
|
239
233
|
.build())
|
240
|
-
|
234
|
+
|
241
235
|
@staticmethod
|
242
236
|
def create_mtls_token_roles_config(port: int = 8008) -> Dict[str, Any]:
|
243
237
|
"""Create mTLS with token and roles configuration."""
|
@@ -229,7 +229,18 @@ class BugfixCertificateGenerator:
|
|
229
229
|
with open(client_info["output_key"], 'w') as f:
|
230
230
|
f.write(result.private_key_pem)
|
231
231
|
|
232
|
+
# Also create a copy in certs/ directory for easier access
|
233
|
+
cert_name_base = client_info["common_name"].replace("-", "_")
|
234
|
+
certs_cert = self.certs_dir / f"{cert_name_base}_client.crt"
|
235
|
+
certs_key = self.certs_dir / f"{cert_name_base}_client.key"
|
236
|
+
|
237
|
+
with open(certs_cert, 'w') as f:
|
238
|
+
f.write(result.certificate_pem)
|
239
|
+
with open(certs_key, 'w') as f:
|
240
|
+
f.write(result.private_key_pem)
|
241
|
+
|
232
242
|
self.print_success(f"{cert_name} certificate generated: {client_info['output_cert']}")
|
243
|
+
self.print_success(f"Also created: {certs_cert} and {certs_key}")
|
233
244
|
return True
|
234
245
|
else:
|
235
246
|
self.print_error(f"Failed to generate {cert_name} certificate")
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.4}/mcp_proxy_adapter/examples/generate_config.py
RENAMED
@@ -12,10 +12,10 @@ import sys
|
|
12
12
|
from pathlib import Path
|
13
13
|
from typing import Dict, Any, Optional
|
14
14
|
|
15
|
-
# Add the
|
16
|
-
sys.path.insert(0, str(Path(__file__).parent
|
15
|
+
# Add the project root to the path to import config_builder
|
16
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
17
17
|
|
18
|
-
from config_builder import ConfigBuilder, ConfigFactory, Protocol, AuthMethod
|
18
|
+
from mcp_proxy_adapter.examples.config_builder import ConfigBuilder, ConfigFactory, Protocol, AuthMethod
|
19
19
|
|
20
20
|
|
21
21
|
def create_config_from_flags(
|
@@ -113,7 +113,7 @@ class FullTestSuiteRunner:
|
|
113
113
|
|
114
114
|
try:
|
115
115
|
# Check if certificate generation script exists
|
116
|
-
cert_script = self.working_dir / "
|
116
|
+
cert_script = self.working_dir / "mcp_proxy_adapter" / "examples" / "generate_certificates.py"
|
117
117
|
if not cert_script.exists():
|
118
118
|
self.print_error(
|
119
119
|
f"Certificate generation script not found: {cert_script}"
|
@@ -167,7 +167,7 @@ class FullTestSuiteRunner:
|
|
167
167
|
|
168
168
|
try:
|
169
169
|
# Check if create_test_configs.py exists
|
170
|
-
config_script = self.working_dir / "create_test_configs.py"
|
170
|
+
config_script = self.working_dir / "mcp_proxy_adapter" / "examples" / "create_test_configs.py"
|
171
171
|
if not config_script.exists():
|
172
172
|
self.print_error(f"Configuration generator not found: {config_script}")
|
173
173
|
return False
|
@@ -194,7 +194,7 @@ class FullTestSuiteRunner:
|
|
194
194
|
# Run the configuration generator
|
195
195
|
cmd = [
|
196
196
|
sys.executable,
|
197
|
-
"create_test_configs.py",
|
197
|
+
"mcp_proxy_adapter/examples/create_test_configs.py",
|
198
198
|
"--comprehensive-config",
|
199
199
|
"comprehensive_config.json",
|
200
200
|
]
|
@@ -124,11 +124,12 @@ class SecurityTestClient:
|
|
124
124
|
def create_ssl_context_for_mtls(self) -> ssl.SSLContext:
|
125
125
|
"""Create SSL context for mTLS connections."""
|
126
126
|
# For mTLS, we need client certificates - check if they exist
|
127
|
-
#
|
128
|
-
# Use
|
129
|
-
|
130
|
-
|
131
|
-
|
127
|
+
# Use absolute paths to avoid issues with working directory
|
128
|
+
# Use newly generated admin_client_client.crt which is signed by the same CA as server
|
129
|
+
project_root = Path(__file__).parent.parent.parent
|
130
|
+
cert_file = str(project_root / "certs" / "admin_client_client.crt")
|
131
|
+
key_file = str(project_root / "keys" / "admin-client_client.key")
|
132
|
+
ca_cert_file = str(project_root / "certs" / "localhost_server.crt")
|
132
133
|
|
133
134
|
# CRITICAL: For mTLS, certificates are REQUIRED
|
134
135
|
if not os.path.exists(cert_file):
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
13
13
|
import sys
|
14
14
|
|
15
15
|
# Add the project root to the path
|
16
|
-
sys.path.insert(0, str(Path(__file__).parent))
|
16
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
17
17
|
|
18
18
|
from mcp_proxy_adapter.config import Config
|
19
19
|
from mcp_proxy_adapter.examples.config_builder import ConfigBuilder, Protocol, AuthMethod
|
@@ -27,7 +27,7 @@ def test_chk_hostname_default_config():
|
|
27
27
|
|
28
28
|
# Default should be HTTP with chk_hostname=False
|
29
29
|
assert config.get("server.protocol") == "http"
|
30
|
-
assert config.get("transport.
|
30
|
+
assert config.get("transport.chk_hostname") is False
|
31
31
|
|
32
32
|
print("✅ Default config: chk_hostname=False for HTTP")
|
33
33
|
|
@@ -49,7 +49,7 @@ def test_chk_hostname_http_config():
|
|
49
49
|
|
50
50
|
# HTTP should have chk_hostname=False
|
51
51
|
assert config.get("server.protocol") == "http"
|
52
|
-
assert config.get("transport.
|
52
|
+
assert config.get("transport.chk_hostname") is False
|
53
53
|
|
54
54
|
print("✅ HTTP config: chk_hostname=False")
|
55
55
|
finally:
|
@@ -74,7 +74,7 @@ def test_chk_hostname_https_config():
|
|
74
74
|
|
75
75
|
# HTTPS should have chk_hostname=True
|
76
76
|
assert config.get("server.protocol") == "https"
|
77
|
-
assert config.get("transport.
|
77
|
+
assert config.get("transport.chk_hostname") is True
|
78
78
|
|
79
79
|
print("✅ HTTPS config: chk_hostname=True")
|
80
80
|
finally:
|
@@ -98,7 +98,7 @@ def test_chk_hostname_mtls_config():
|
|
98
98
|
|
99
99
|
# mTLS should have chk_hostname=True
|
100
100
|
assert config.get("server.protocol") == "mtls"
|
101
|
-
assert config.get("transport.
|
101
|
+
assert config.get("transport.chk_hostname") is True
|
102
102
|
|
103
103
|
print("✅ mTLS config: chk_hostname=True")
|
104
104
|
finally:
|
@@ -114,10 +114,7 @@ def test_chk_hostname_override():
|
|
114
114
|
# Add transport section if it doesn't exist
|
115
115
|
if "transport" not in https_config:
|
116
116
|
https_config["transport"] = {}
|
117
|
-
|
118
|
-
https_config["transport"]["ssl"] = {}
|
119
|
-
https_config["transport"]["ssl"]["chk_hostname"] = False
|
120
|
-
https_config["transport"]["ssl"]["_chk_hostname_user_set"] = True
|
117
|
+
https_config["transport"]["chk_hostname"] = False
|
121
118
|
|
122
119
|
# Save to temporary file and load with Config
|
123
120
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
@@ -130,7 +127,7 @@ def test_chk_hostname_override():
|
|
130
127
|
|
131
128
|
# Should respect the override
|
132
129
|
assert config.get("server.protocol") == "https"
|
133
|
-
assert config.get("transport.
|
130
|
+
assert config.get("transport.chk_hostname") is False
|
134
131
|
|
135
132
|
print("✅ HTTPS config with chk_hostname=False override works")
|
136
133
|
finally:
|