mcp-proxy-adapter 6.9.28__py3-none-any.whl → 6.9.30__py3-none-any.whl
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.
Potentially problematic release.
This version of mcp-proxy-adapter might be problematic. Click here for more details.
- mcp_proxy_adapter/__init__.py +10 -0
- mcp_proxy_adapter/__main__.py +8 -21
- mcp_proxy_adapter/api/app.py +10 -913
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +243 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_manager.py +166 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +78 -199
- mcp_proxy_adapter/api/middleware/__init__.py +1 -44
- mcp_proxy_adapter/api/middleware/base.py +0 -42
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -85
- mcp_proxy_adapter/api/middleware/error_handling.py +1 -127
- mcp_proxy_adapter/api/middleware/factory.py +0 -94
- mcp_proxy_adapter/api/middleware/logging.py +0 -112
- mcp_proxy_adapter/api/middleware/performance.py +0 -35
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +2 -98
- mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -37
- mcp_proxy_adapter/api/middleware/unified_security.py +10 -10
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -118
- mcp_proxy_adapter/api/openapi/__init__.py +21 -0
- mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
- mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
- mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
- mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
- mcp_proxy_adapter/api/schemas.py +0 -61
- mcp_proxy_adapter/api/tool_integration.py +0 -117
- mcp_proxy_adapter/api/tools.py +0 -46
- mcp_proxy_adapter/cli/__init__.py +12 -0
- mcp_proxy_adapter/cli/commands/__init__.py +15 -0
- mcp_proxy_adapter/cli/commands/client.py +100 -0
- mcp_proxy_adapter/cli/commands/config_generate.py +21 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +36 -0
- mcp_proxy_adapter/cli/commands/generate.py +259 -0
- mcp_proxy_adapter/cli/commands/server.py +174 -0
- mcp_proxy_adapter/cli/commands/sets.py +128 -0
- mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
- mcp_proxy_adapter/cli/examples/__init__.py +8 -0
- mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
- mcp_proxy_adapter/cli/examples/https_token.py +96 -0
- mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
- mcp_proxy_adapter/cli/main.py +63 -0
- mcp_proxy_adapter/cli/parser.py +324 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client.py +406 -0
- mcp_proxy_adapter/client/proxy.py +45 -0
- mcp_proxy_adapter/commands/__init__.py +44 -28
- mcp_proxy_adapter/commands/auth_validation_command.py +7 -344
- mcp_proxy_adapter/commands/base.py +19 -43
- mcp_proxy_adapter/commands/builtin_commands.py +0 -75
- mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
- mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
- mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
- mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
- mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
- mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
- mcp_proxy_adapter/commands/catalog_manager.py +58 -928
- mcp_proxy_adapter/commands/cert_monitor_command.py +0 -88
- mcp_proxy_adapter/commands/certificate_management_command.py +0 -45
- mcp_proxy_adapter/commands/command_registry.py +172 -904
- mcp_proxy_adapter/commands/config_command.py +0 -28
- mcp_proxy_adapter/commands/dependency_container.py +1 -70
- mcp_proxy_adapter/commands/dependency_manager.py +0 -128
- mcp_proxy_adapter/commands/echo_command.py +0 -34
- mcp_proxy_adapter/commands/health_command.py +0 -3
- mcp_proxy_adapter/commands/help_command.py +0 -159
- mcp_proxy_adapter/commands/hooks.py +0 -137
- mcp_proxy_adapter/commands/key_management_command.py +0 -25
- mcp_proxy_adapter/commands/load_command.py +7 -78
- mcp_proxy_adapter/commands/plugins_command.py +0 -16
- mcp_proxy_adapter/commands/protocol_management_command.py +0 -28
- mcp_proxy_adapter/commands/proxy_registration_command.py +0 -88
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +0 -43
- mcp_proxy_adapter/commands/registry/__init__.py +18 -0
- mcp_proxy_adapter/commands/registry/command_info.py +103 -0
- mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
- mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
- mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
- mcp_proxy_adapter/commands/reload_command.py +0 -80
- mcp_proxy_adapter/commands/result.py +25 -77
- mcp_proxy_adapter/commands/role_test_command.py +0 -44
- mcp_proxy_adapter/commands/roles_management_command.py +0 -199
- mcp_proxy_adapter/commands/security_command.py +0 -30
- mcp_proxy_adapter/commands/settings_command.py +0 -68
- mcp_proxy_adapter/commands/ssl_setup_command.py +0 -42
- mcp_proxy_adapter/commands/token_management_command.py +0 -1
- mcp_proxy_adapter/commands/transport_management_command.py +0 -20
- mcp_proxy_adapter/commands/unload_command.py +0 -71
- mcp_proxy_adapter/config.py +15 -626
- mcp_proxy_adapter/core/__init__.py +5 -39
- mcp_proxy_adapter/core/app_factory.py +14 -36
- mcp_proxy_adapter/core/app_runner.py +0 -27
- mcp_proxy_adapter/core/auth_validator.py +1 -93
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +371 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +183 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +110 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +70 -0
- mcp_proxy_adapter/core/certificate_utils.py +64 -903
- mcp_proxy_adapter/core/client.py +10 -9
- mcp_proxy_adapter/core/client_manager.py +0 -19
- mcp_proxy_adapter/core/client_security.py +0 -2
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +195 -0
- mcp_proxy_adapter/core/config/config_factory.py +22 -0
- mcp_proxy_adapter/core/config/config_loader.py +66 -0
- mcp_proxy_adapter/core/config/feature_manager.py +31 -0
- mcp_proxy_adapter/core/config/simple_config.py +112 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +50 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +96 -0
- mcp_proxy_adapter/core/config_converter.py +0 -186
- mcp_proxy_adapter/core/config_validator.py +96 -1238
- mcp_proxy_adapter/core/errors.py +7 -42
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +2 -22
- mcp_proxy_adapter/core/mtls_asgi.py +0 -20
- mcp_proxy_adapter/core/mtls_asgi_app.py +0 -12
- mcp_proxy_adapter/core/mtls_proxy.py +0 -80
- mcp_proxy_adapter/core/mtls_server.py +3 -173
- mcp_proxy_adapter/core/protocol_manager.py +1 -191
- mcp_proxy_adapter/core/proxy/__init__.py +22 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +27 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +137 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +60 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +0 -1
- mcp_proxy_adapter/core/proxy_registration.py +36 -913
- mcp_proxy_adapter/core/role_utils.py +0 -308
- mcp_proxy_adapter/core/security_adapter.py +1 -36
- mcp_proxy_adapter/core/security_factory.py +1 -150
- mcp_proxy_adapter/core/security_integration.py +0 -33
- mcp_proxy_adapter/core/server_adapter.py +1 -40
- mcp_proxy_adapter/core/server_engine.py +2 -173
- mcp_proxy_adapter/core/settings.py +0 -127
- mcp_proxy_adapter/core/signal_handler.py +0 -65
- mcp_proxy_adapter/core/ssl_utils.py +19 -137
- mcp_proxy_adapter/core/transport_manager.py +0 -151
- mcp_proxy_adapter/core/unified_config_adapter.py +1 -193
- mcp_proxy_adapter/core/utils.py +1 -182
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +211 -0
- mcp_proxy_adapter/core/validation/file_validator.py +73 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +191 -0
- mcp_proxy_adapter/core/validation/security_validator.py +58 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +33 -652
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -23
- mcp_proxy_adapter/examples/check_config.py +0 -2
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/config_builder.py +13 -2
- mcp_proxy_adapter/examples/config_cli.py +0 -1
- mcp_proxy_adapter/examples/create_test_configs.py +0 -46
- mcp_proxy_adapter/examples/debug_request_state.py +0 -1
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -47
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -45
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +0 -12
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +0 -12
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +0 -7
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -2
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -59
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -54
- mcp_proxy_adapter/examples/full_application/main.py +186 -150
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -107
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +0 -24
- mcp_proxy_adapter/examples/full_application/test_server.py +0 -58
- mcp_proxy_adapter/examples/generate_config.py +65 -11
- mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
- mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
- mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
- mcp_proxy_adapter/examples/queue_server_example.py +85 -0
- mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
- mcp_proxy_adapter/examples/required_certificates.py +0 -2
- mcp_proxy_adapter/examples/run_full_test_suite.py +0 -29
- mcp_proxy_adapter/examples/run_proxy_server.py +31 -71
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -27
- mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
- mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
- mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
- mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
- mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
- mcp_proxy_adapter/examples/security_test_client.py +24 -1075
- mcp_proxy_adapter/examples/setup/__init__.py +24 -0
- mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
- mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
- mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
- mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
- mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
- mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +133 -1425
- mcp_proxy_adapter/examples/test_config.py +0 -3
- mcp_proxy_adapter/examples/test_config_builder.py +25 -405
- mcp_proxy_adapter/examples/test_examples.py +0 -1
- mcp_proxy_adapter/examples/test_framework_complete.py +0 -2
- mcp_proxy_adapter/examples/test_mcp_server.py +0 -1
- mcp_proxy_adapter/examples/test_protocol_examples.py +0 -1
- mcp_proxy_adapter/examples/universal_client.py +0 -6
- mcp_proxy_adapter/examples/update_config_certificates.py +0 -1
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +0 -1
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +0 -187
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +70 -62
- mcp_proxy_adapter/openapi.py +0 -22
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.30.dist-info}/METADATA +2 -1
- mcp_proxy_adapter-6.9.30.dist-info/RECORD +235 -0
- {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.30.dist-info}/entry_points.txt +1 -1
- mcp_proxy_adapter-6.9.28.dist-info/RECORD +0 -149
- {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.30.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.30.dist-info}/top_level.txt +0 -0
|
@@ -6,8 +6,8 @@ including HTTP, HTTPS, and MTLS protocols with their respective ports.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import ssl
|
|
9
|
-
from typing import Dict, List, Optional, Tuple, Union
|
|
10
9
|
from urllib.parse import urlparse
|
|
10
|
+
from typing import Dict, List, Any, Optional
|
|
11
11
|
|
|
12
12
|
from mcp_proxy_adapter.config import config
|
|
13
13
|
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
@@ -89,49 +89,8 @@ class ProtocolManager:
|
|
|
89
89
|
f"Protocol manager loaded config: enabled={self.enabled}, allowed_protocols={self.allowed_protocols}"
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
def _is_ssl_enabled(self, current_config: Dict) -> bool:
|
|
93
|
-
"""
|
|
94
|
-
Check if SSL is enabled in configuration.
|
|
95
|
-
|
|
96
|
-
Args:
|
|
97
|
-
current_config: Current configuration dictionary
|
|
98
|
-
|
|
99
|
-
Returns:
|
|
100
|
-
True if SSL is enabled, False otherwise
|
|
101
|
-
"""
|
|
102
|
-
# Try security framework SSL config first
|
|
103
|
-
security_config = current_config.get("security", {})
|
|
104
|
-
ssl_config = security_config.get("ssl", {})
|
|
105
92
|
|
|
106
|
-
if ssl_config.get("enabled", False):
|
|
107
|
-
get_global_logger().debug("SSL enabled via security.ssl configuration")
|
|
108
|
-
return True
|
|
109
93
|
|
|
110
|
-
# Fallback to legacy SSL config
|
|
111
|
-
legacy_ssl_config = current_config.get("ssl", {})
|
|
112
|
-
if legacy_ssl_config.get("enabled", False):
|
|
113
|
-
get_global_logger().debug("SSL enabled via legacy ssl configuration")
|
|
114
|
-
return True
|
|
115
|
-
|
|
116
|
-
get_global_logger().debug("SSL is disabled in configuration")
|
|
117
|
-
return False
|
|
118
|
-
|
|
119
|
-
def update_config(self, new_config: Dict):
|
|
120
|
-
"""
|
|
121
|
-
Update configuration and reload protocol settings.
|
|
122
|
-
|
|
123
|
-
Args:
|
|
124
|
-
new_config: New configuration dictionary
|
|
125
|
-
"""
|
|
126
|
-
self.app_config = new_config
|
|
127
|
-
self._load_config()
|
|
128
|
-
get_global_logger().info(
|
|
129
|
-
f"Protocol manager configuration updated: allowed_protocols={self.allowed_protocols}"
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
def reload_config(self):
|
|
133
|
-
"""Reload protocol configuration from global config."""
|
|
134
|
-
self._load_config()
|
|
135
94
|
|
|
136
95
|
def is_protocol_allowed(self, protocol: str) -> bool:
|
|
137
96
|
"""
|
|
@@ -157,35 +116,7 @@ class ProtocolManager:
|
|
|
157
116
|
get_global_logger().debug(f"🔍 ProtocolManager.is_protocol_allowed - Protocol '{protocol}' allowed: {is_allowed}")
|
|
158
117
|
return is_allowed
|
|
159
118
|
|
|
160
|
-
def get_protocol_port(self, protocol: str) -> Optional[int]:
|
|
161
|
-
"""
|
|
162
|
-
Get the configured port for a specific protocol.
|
|
163
119
|
|
|
164
|
-
Args:
|
|
165
|
-
protocol: Protocol name (http, https, mtls)
|
|
166
|
-
|
|
167
|
-
Returns:
|
|
168
|
-
Port number if configured, None otherwise
|
|
169
|
-
"""
|
|
170
|
-
protocol_lower = protocol.lower()
|
|
171
|
-
protocol_config = self.protocols_config.get(protocol_lower, {})
|
|
172
|
-
|
|
173
|
-
if not protocol_config.get("enabled", False):
|
|
174
|
-
get_global_logger().debug(f"Protocol '{protocol}' is not enabled")
|
|
175
|
-
return None
|
|
176
|
-
|
|
177
|
-
port = protocol_config.get("port")
|
|
178
|
-
get_global_logger().debug(f"Protocol '{protocol}' port: {port}")
|
|
179
|
-
return port
|
|
180
|
-
|
|
181
|
-
def get_allowed_protocols(self) -> List[str]:
|
|
182
|
-
"""
|
|
183
|
-
Get list of all allowed protocols.
|
|
184
|
-
|
|
185
|
-
Returns:
|
|
186
|
-
List of allowed protocol names
|
|
187
|
-
"""
|
|
188
|
-
return self.allowed_protocols.copy()
|
|
189
120
|
|
|
190
121
|
def get_protocol_config(self, protocol: str) -> Dict:
|
|
191
122
|
"""
|
|
@@ -207,33 +138,6 @@ class ProtocolManager:
|
|
|
207
138
|
return {}
|
|
208
139
|
return {}
|
|
209
140
|
|
|
210
|
-
def validate_url_protocol(self, url: str) -> Tuple[bool, Optional[str]]:
|
|
211
|
-
"""
|
|
212
|
-
Validate if the URL protocol is allowed.
|
|
213
|
-
|
|
214
|
-
Args:
|
|
215
|
-
url: URL to validate
|
|
216
|
-
|
|
217
|
-
Returns:
|
|
218
|
-
Tuple of (is_allowed, error_message)
|
|
219
|
-
"""
|
|
220
|
-
try:
|
|
221
|
-
parsed = urlparse(url)
|
|
222
|
-
protocol = parsed.scheme.lower()
|
|
223
|
-
|
|
224
|
-
if not protocol:
|
|
225
|
-
return False, "No protocol specified in URL"
|
|
226
|
-
|
|
227
|
-
if not self.is_protocol_allowed(protocol):
|
|
228
|
-
return (
|
|
229
|
-
False,
|
|
230
|
-
f"Protocol '{protocol}' is not allowed. Allowed protocols: {self.allowed_protocols}",
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
return True, None
|
|
234
|
-
|
|
235
|
-
except Exception as e:
|
|
236
|
-
return False, f"Invalid URL format: {str(e)}"
|
|
237
141
|
|
|
238
142
|
def get_ssl_context_for_protocol(self, protocol: str) -> Optional[ssl.SSLContext]:
|
|
239
143
|
"""
|
|
@@ -319,104 +223,10 @@ class ProtocolManager:
|
|
|
319
223
|
# Return empty config if SSL is disabled
|
|
320
224
|
return {"enabled": False}
|
|
321
225
|
|
|
322
|
-
def get_protocol_info(self) -> Dict[str, Dict]:
|
|
323
|
-
"""
|
|
324
|
-
Get information about all configured protocols.
|
|
325
226
|
|
|
326
|
-
Returns:
|
|
327
|
-
Dictionary with protocol information
|
|
328
|
-
"""
|
|
329
|
-
info = {}
|
|
330
|
-
|
|
331
|
-
for protocol in ["http", "https", "mtls"]:
|
|
332
|
-
protocol_config = self.get_protocol_config(protocol)
|
|
333
|
-
info[protocol] = {
|
|
334
|
-
"enabled": protocol_config.get("enabled", False),
|
|
335
|
-
"allowed": self.is_protocol_allowed(protocol),
|
|
336
|
-
"port": protocol_config.get("port"),
|
|
337
|
-
"requires_ssl": protocol in ["https", "mtls"],
|
|
338
|
-
"ssl_context_available": self.get_ssl_context_for_protocol(protocol)
|
|
339
|
-
is not None,
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return info
|
|
343
|
-
|
|
344
|
-
def validate_protocol_configuration(self) -> List[str]:
|
|
345
|
-
"""
|
|
346
|
-
Validate the current protocol configuration.
|
|
347
|
-
|
|
348
|
-
Returns:
|
|
349
|
-
List of validation errors (empty if configuration is valid)
|
|
350
|
-
"""
|
|
351
|
-
errors = []
|
|
352
|
-
|
|
353
|
-
if not self.enabled:
|
|
354
|
-
return errors
|
|
355
|
-
|
|
356
|
-
# Check if allowed protocols are configured
|
|
357
|
-
for protocol in self.allowed_protocols:
|
|
358
|
-
if protocol not in ["http", "https", "mtls"]:
|
|
359
|
-
errors.append(f"Unknown protocol '{protocol}' in allowed_protocols")
|
|
360
|
-
continue
|
|
361
|
-
|
|
362
|
-
protocol_config = self.get_protocol_config(protocol)
|
|
363
|
-
|
|
364
|
-
if not protocol_config.get("enabled", False):
|
|
365
|
-
errors.append(
|
|
366
|
-
f"Protocol '{protocol}' is in allowed_protocols but not enabled"
|
|
367
|
-
)
|
|
368
|
-
continue
|
|
369
|
-
|
|
370
|
-
port = protocol_config.get("port")
|
|
371
|
-
if not port:
|
|
372
|
-
errors.append(
|
|
373
|
-
f"Protocol '{protocol}' is enabled but no port configured"
|
|
374
|
-
)
|
|
375
|
-
continue
|
|
376
|
-
|
|
377
|
-
# Check SSL requirements
|
|
378
|
-
if protocol in ["https", "mtls"]:
|
|
379
|
-
# Use provided config or fallback to global config
|
|
380
|
-
current_config = (
|
|
381
|
-
self.app_config if self.app_config is not None else config.get_all()
|
|
382
|
-
)
|
|
383
|
-
ssl_config = self._get_ssl_config(current_config)
|
|
384
|
-
|
|
385
|
-
if not ssl_config.get("enabled", False):
|
|
386
|
-
errors.append(
|
|
387
|
-
f"Protocol '{protocol}' requires SSL but SSL is disabled"
|
|
388
|
-
)
|
|
389
|
-
elif not ssl_config.get("cert_file") or not ssl_config.get("key_file"):
|
|
390
|
-
errors.append(
|
|
391
|
-
f"Protocol '{protocol}' requires SSL but certificate files not configured"
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
return errors
|
|
395
227
|
|
|
396
228
|
|
|
397
229
|
# Global protocol manager instance - will be updated with config when needed
|
|
398
230
|
protocol_manager = None
|
|
399
231
|
|
|
400
232
|
|
|
401
|
-
def get_protocol_manager(app_config: Optional[Dict] = None) -> ProtocolManager:
|
|
402
|
-
"""
|
|
403
|
-
Get protocol manager instance with current configuration.
|
|
404
|
-
|
|
405
|
-
Args:
|
|
406
|
-
app_config: Application configuration dictionary (optional)
|
|
407
|
-
|
|
408
|
-
Returns:
|
|
409
|
-
ProtocolManager instance
|
|
410
|
-
"""
|
|
411
|
-
global protocol_manager
|
|
412
|
-
|
|
413
|
-
# If no app_config provided, use global config
|
|
414
|
-
if app_config is None:
|
|
415
|
-
app_config = config.get_all()
|
|
416
|
-
|
|
417
|
-
# Create new instance if none exists or config changed
|
|
418
|
-
if protocol_manager is None or protocol_manager.app_config != app_config:
|
|
419
|
-
protocol_manager = ProtocolManager(app_config)
|
|
420
|
-
get_global_logger().info("Protocol manager created with new configuration")
|
|
421
|
-
|
|
422
|
-
return protocol_manager
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Proxy registration package for MCP Proxy Adapter.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .proxy_registration_manager import ProxyRegistrationManager, ProxyRegistrationError
|
|
9
|
+
from .auth_manager import AuthManager
|
|
10
|
+
from .ssl_manager import SSLManager
|
|
11
|
+
from .registration_client import RegistrationClient
|
|
12
|
+
from .proxy_registration import initialize_proxy_registration, get_proxy_registration_status
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"ProxyRegistrationManager",
|
|
16
|
+
"ProxyRegistrationError",
|
|
17
|
+
"AuthManager",
|
|
18
|
+
"SSLManager",
|
|
19
|
+
"RegistrationClient",
|
|
20
|
+
"initialize_proxy_registration",
|
|
21
|
+
"get_proxy_registration_status",
|
|
22
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Authentication management for proxy registration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AuthManager:
|
|
13
|
+
"""Manager for authentication in proxy registration."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client_security, registration_config: Dict[str, Any]):
|
|
16
|
+
"""
|
|
17
|
+
Initialize authentication manager.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
client_security: Client security manager instance
|
|
21
|
+
registration_config: Registration configuration
|
|
22
|
+
"""
|
|
23
|
+
self.client_security = client_security
|
|
24
|
+
self.registration_config = registration_config
|
|
25
|
+
self.logger = get_global_logger()
|
|
26
|
+
|
|
27
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Main proxy registration manager for MCP Proxy Adapter.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
11
|
+
from mcp_proxy_adapter.core.client_security import create_client_security_manager
|
|
12
|
+
from .registration_client import RegistrationClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ProxyRegistrationError(Exception):
|
|
16
|
+
"""Exception raised when proxy registration fails."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ProxyRegistrationManager:
|
|
21
|
+
"""
|
|
22
|
+
Manager for proxy registration functionality with security framework integration.
|
|
23
|
+
|
|
24
|
+
Handles automatic registration and unregistration of the server
|
|
25
|
+
with the MCP proxy server using secure authentication methods.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, config: Dict[str, Any]):
|
|
29
|
+
"""
|
|
30
|
+
Initialize the proxy registration manager.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
config: Application configuration
|
|
34
|
+
"""
|
|
35
|
+
self.config = config
|
|
36
|
+
self.logger = get_global_logger()
|
|
37
|
+
|
|
38
|
+
# Get registration configuration
|
|
39
|
+
self.registration_config = config.get("proxy_registration", {})
|
|
40
|
+
|
|
41
|
+
# Initialize client security
|
|
42
|
+
self.client_security = create_client_security_manager(config)
|
|
43
|
+
|
|
44
|
+
# Registration state
|
|
45
|
+
self.proxy_url = self.registration_config.get("proxy_url")
|
|
46
|
+
self.server_url = None
|
|
47
|
+
self.registered = False
|
|
48
|
+
self.registration_time = None
|
|
49
|
+
|
|
50
|
+
# Initialize registration client
|
|
51
|
+
self.registration_client = RegistrationClient(
|
|
52
|
+
self.client_security,
|
|
53
|
+
self.registration_config,
|
|
54
|
+
config,
|
|
55
|
+
self.proxy_url
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def is_enabled(self) -> bool:
|
|
59
|
+
"""
|
|
60
|
+
Check if proxy registration is enabled.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
True if enabled, False otherwise
|
|
64
|
+
"""
|
|
65
|
+
return self.registration_config.get("enabled", False)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def register(self) -> bool:
|
|
69
|
+
"""
|
|
70
|
+
Register server with proxy.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
True if registration successful, False otherwise
|
|
74
|
+
"""
|
|
75
|
+
if not self.is_enabled():
|
|
76
|
+
self.logger.info("Proxy registration is disabled")
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
if not self.server_url:
|
|
80
|
+
self.logger.error("Server URL not set for registration")
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
if not self.proxy_url:
|
|
84
|
+
self.logger.error("Proxy URL not configured")
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
self.logger.info(f"Registering with proxy: {self.proxy_url}")
|
|
89
|
+
|
|
90
|
+
success = await self.registration_client.register(self.server_url)
|
|
91
|
+
|
|
92
|
+
if success:
|
|
93
|
+
self.registered = True
|
|
94
|
+
self.registration_time = time.time()
|
|
95
|
+
self.logger.info("✅ Proxy registration completed successfully")
|
|
96
|
+
else:
|
|
97
|
+
self.logger.error("❌ Proxy registration failed")
|
|
98
|
+
|
|
99
|
+
return success
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
self.logger.error(f"Registration error: {e}")
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
async def unregister(self) -> bool:
|
|
106
|
+
"""
|
|
107
|
+
Unregister server from proxy.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
True if unregistration successful, False otherwise
|
|
111
|
+
"""
|
|
112
|
+
if not self.is_enabled():
|
|
113
|
+
self.logger.info("Proxy registration is disabled")
|
|
114
|
+
return True
|
|
115
|
+
|
|
116
|
+
if not self.registered:
|
|
117
|
+
self.logger.info("Server not registered, skipping unregistration")
|
|
118
|
+
return True
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
self.logger.info("Unregistering from proxy")
|
|
122
|
+
|
|
123
|
+
success = await self.registration_client.unregister()
|
|
124
|
+
|
|
125
|
+
if success:
|
|
126
|
+
self.registered = False
|
|
127
|
+
self.registration_time = None
|
|
128
|
+
self.logger.info("✅ Proxy unregistration completed successfully")
|
|
129
|
+
else:
|
|
130
|
+
self.logger.warning("⚠️ Proxy unregistration failed")
|
|
131
|
+
|
|
132
|
+
return success
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
self.logger.error(f"Unregistration error: {e}")
|
|
136
|
+
return False
|
|
137
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Registration client for proxy registration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
import traceback
|
|
10
|
+
|
|
11
|
+
import aiohttp
|
|
12
|
+
|
|
13
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
14
|
+
from .auth_manager import AuthManager
|
|
15
|
+
from .ssl_manager import SSLManager
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class RegistrationClient:
|
|
19
|
+
"""Client for proxy registration operations."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, client_security, registration_config: Dict[str, Any], config: Dict[str, Any], proxy_url: str):
|
|
22
|
+
"""
|
|
23
|
+
Initialize registration client.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
client_security: Client security manager instance
|
|
27
|
+
registration_config: Registration configuration
|
|
28
|
+
config: Application configuration
|
|
29
|
+
proxy_url: Proxy server URL
|
|
30
|
+
"""
|
|
31
|
+
self.client_security = client_security
|
|
32
|
+
self.registration_config = registration_config
|
|
33
|
+
self.config = config
|
|
34
|
+
self.proxy_url = proxy_url
|
|
35
|
+
self.logger = get_global_logger()
|
|
36
|
+
|
|
37
|
+
# Initialize managers
|
|
38
|
+
self.auth_manager = AuthManager(client_security, registration_config)
|
|
39
|
+
self.ssl_manager = SSLManager(client_security, registration_config, config, proxy_url)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _prepare_registration_data(self, server_url: str) -> Dict[str, Any]:
|
|
44
|
+
"""
|
|
45
|
+
Prepare registration data.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
server_url: Server URL to register
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Registration data dictionary
|
|
52
|
+
"""
|
|
53
|
+
return {
|
|
54
|
+
"server_id": self.registration_config.get("server_id"),
|
|
55
|
+
"server_name": self.registration_config.get("server_name"),
|
|
56
|
+
"server_url": server_url,
|
|
57
|
+
"description": self.registration_config.get("description", ""),
|
|
58
|
+
"version": self.registration_config.get("version", "1.0.0"),
|
|
59
|
+
"capabilities": self.registration_config.get("capabilities", []),
|
|
60
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
SSL management for proxy registration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import ssl
|
|
9
|
+
from typing import Dict, Any, Optional
|
|
10
|
+
from urllib.parse import urlparse
|
|
11
|
+
|
|
12
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SSLManager:
|
|
16
|
+
"""Manager for SSL connections in proxy registration."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, client_security, registration_config: Dict[str, Any], config: Dict[str, Any], proxy_url: str):
|
|
19
|
+
"""
|
|
20
|
+
Initialize SSL manager.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
client_security: Client security manager instance
|
|
24
|
+
registration_config: Registration configuration
|
|
25
|
+
config: Application configuration
|
|
26
|
+
proxy_url: Proxy server URL
|
|
27
|
+
"""
|
|
28
|
+
self.client_security = client_security
|
|
29
|
+
self.registration_config = registration_config
|
|
30
|
+
self.config = config
|
|
31
|
+
self.proxy_url = proxy_url
|
|
32
|
+
self.logger = get_global_logger()
|
|
33
|
+
|
|
34
|
+
def create_ssl_context(self) -> Optional[ssl.SSLContext]:
|
|
35
|
+
"""
|
|
36
|
+
Create SSL context for secure connections using registration SSL configuration.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
SSL context or None if SSL not needed
|
|
40
|
+
"""
|
|
41
|
+
self.logger.debug("_create_ssl_context called")
|
|
42
|
+
|
|
43
|
+
# Decide SSL strictly by proxy URL scheme: use SSL only for https proxy URLs
|
|
44
|
+
try:
|
|
45
|
+
scheme = urlparse(self.proxy_url).scheme if self.proxy_url else "http"
|
|
46
|
+
if scheme.lower() != "https":
|
|
47
|
+
self.logger.debug("Proxy URL is HTTP, skipping SSL context creation for registration")
|
|
48
|
+
return None
|
|
49
|
+
except Exception:
|
|
50
|
+
self.logger.debug("Failed to parse proxy_url, assuming HTTP and skipping SSL context")
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
if not self.client_security:
|
|
54
|
+
self.logger.debug("SSL context creation failed: client_security is None")
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
# Check if SSL is enabled for registration
|
|
59
|
+
cert_config = self.registration_config.get("certificate", {})
|
|
60
|
+
ssl_config = self.registration_config.get("ssl", {})
|
|
61
|
+
|
|
62
|
+
# FALLBACK: if no explicit registration SSL/certs provided, reuse global SSL config
|
|
63
|
+
if not cert_config and not ssl_config:
|
|
64
|
+
global_ssl = self.config.get("security", {}).get("ssl", {}) or self.config.get("ssl", {})
|
|
65
|
+
if global_ssl:
|
|
66
|
+
# Map global ssl to registration-style configs
|
|
67
|
+
mapped_cert = {}
|
|
68
|
+
if global_ssl.get("cert_file") and global_ssl.get("key_file"):
|
|
69
|
+
mapped_cert = {
|
|
70
|
+
"cert_file": global_ssl.get("cert_file"),
|
|
71
|
+
"key_file": global_ssl.get("key_file"),
|
|
72
|
+
}
|
|
73
|
+
mapped_ssl = {}
|
|
74
|
+
if global_ssl.get("ca_cert"):
|
|
75
|
+
mapped_ssl["ca_cert"] = global_ssl.get("ca_cert")
|
|
76
|
+
if global_ssl.get("verify_client") is not None:
|
|
77
|
+
mapped_ssl["verify_mode"] = (
|
|
78
|
+
"CERT_REQUIRED" if global_ssl.get("verify_client") else "CERT_NONE"
|
|
79
|
+
)
|
|
80
|
+
cert_config = mapped_cert
|
|
81
|
+
ssl_config = mapped_ssl
|
|
82
|
+
|
|
83
|
+
# Use client security manager to create SSL context
|
|
84
|
+
if cert_config or ssl_config:
|
|
85
|
+
ssl_context = self.client_security.create_ssl_context(
|
|
86
|
+
cert_config=cert_config,
|
|
87
|
+
ssl_config=ssl_config
|
|
88
|
+
)
|
|
89
|
+
if ssl_context:
|
|
90
|
+
self.logger.debug("SSL context created successfully for registration")
|
|
91
|
+
return ssl_context
|
|
92
|
+
else:
|
|
93
|
+
self.logger.warning("Failed to create SSL context for registration")
|
|
94
|
+
return None
|
|
95
|
+
else:
|
|
96
|
+
self.logger.debug("No SSL configuration found for registration")
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
except Exception as e:
|
|
100
|
+
self.logger.error(f"Error creating SSL context for registration: {e}")
|
|
101
|
+
return None
|
|
@@ -12,7 +12,6 @@ mutual TLS. Designed to be used by services built on this framework to:
|
|
|
12
12
|
This client intentionally avoids framework-specific configuration objects and
|
|
13
13
|
accepts explicit parameters for clarity and portability.
|
|
14
14
|
"""
|
|
15
|
-
from __future__ import annotations
|
|
16
15
|
|
|
17
16
|
import json
|
|
18
17
|
import ssl
|