mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__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 +47 -0
- mcp_proxy_adapter/__main__.py +13 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +66 -0
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +400 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_context.py +356 -0
- mcp_proxy_adapter/api/core/registration_manager.py +307 -0
- mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +181 -0
- mcp_proxy_adapter/api/middleware/__init__.py +21 -0
- mcp_proxy_adapter/api/middleware/base.py +54 -0
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
- mcp_proxy_adapter/api/middleware/factory.py +147 -0
- mcp_proxy_adapter/api/middleware/logging.py +31 -0
- mcp_proxy_adapter/api/middleware/performance.py +51 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
- 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 +270 -0
- mcp_proxy_adapter/api/tool_integration.py +131 -0
- mcp_proxy_adapter/api/tools.py +163 -0
- 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 +105 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +94 -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 +132 -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 +338 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
- mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
- mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
- mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
- mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
- mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
- mcp_proxy_adapter/client/proxy.py +123 -0
- mcp_proxy_adapter/commands/__init__.py +66 -0
- mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
- mcp_proxy_adapter/commands/base.py +389 -0
- mcp_proxy_adapter/commands/builtin_commands.py +30 -0
- 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 +97 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
- mcp_proxy_adapter/commands/command_registry.py +298 -0
- mcp_proxy_adapter/commands/config_command.py +102 -0
- mcp_proxy_adapter/commands/dependency_container.py +40 -0
- mcp_proxy_adapter/commands/dependency_manager.py +143 -0
- mcp_proxy_adapter/commands/echo_command.py +48 -0
- mcp_proxy_adapter/commands/health_command.py +142 -0
- mcp_proxy_adapter/commands/help_command.py +175 -0
- mcp_proxy_adapter/commands/hooks.py +172 -0
- mcp_proxy_adapter/commands/key_management_command.py +484 -0
- mcp_proxy_adapter/commands/load_command.py +123 -0
- mcp_proxy_adapter/commands/plugins_command.py +246 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +76 -0
- 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 +136 -0
- mcp_proxy_adapter/commands/result.py +157 -0
- mcp_proxy_adapter/commands/role_test_command.py +99 -0
- mcp_proxy_adapter/commands/roles_management_command.py +502 -0
- mcp_proxy_adapter/commands/security_command.py +472 -0
- mcp_proxy_adapter/commands/settings_command.py +113 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
- mcp_proxy_adapter/commands/token_management_command.py +500 -0
- mcp_proxy_adapter/commands/transport_management_command.py +129 -0
- mcp_proxy_adapter/commands/unload_command.py +92 -0
- mcp_proxy_adapter/config.py +32 -0
- mcp_proxy_adapter/core/__init__.py +8 -0
- mcp_proxy_adapter/core/app_factory.py +560 -0
- mcp_proxy_adapter/core/app_runner.py +318 -0
- mcp_proxy_adapter/core/auth_validator.py +508 -0
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
- mcp_proxy_adapter/core/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/client.py +608 -0
- mcp_proxy_adapter/core/client_manager.py +271 -0
- mcp_proxy_adapter/core/client_security.py +411 -0
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +237 -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 +204 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
- mcp_proxy_adapter/core/config_converter.py +252 -0
- mcp_proxy_adapter/core/config_validator.py +211 -0
- mcp_proxy_adapter/core/crl_utils.py +362 -0
- mcp_proxy_adapter/core/errors.py +276 -0
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +250 -0
- mcp_proxy_adapter/core/mtls_asgi.py +140 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/mtls_proxy.py +229 -0
- mcp_proxy_adapter/core/mtls_server.py +154 -0
- mcp_proxy_adapter/core/protocol_manager.py +232 -0
- mcp_proxy_adapter/core/proxy/__init__.py +19 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +184 -0
- mcp_proxy_adapter/core/proxy_registration.py +80 -0
- mcp_proxy_adapter/core/role_utils.py +103 -0
- mcp_proxy_adapter/core/security_adapter.py +343 -0
- mcp_proxy_adapter/core/security_factory.py +96 -0
- mcp_proxy_adapter/core/security_integration.py +342 -0
- mcp_proxy_adapter/core/server_adapter.py +251 -0
- mcp_proxy_adapter/core/server_engine.py +217 -0
- mcp_proxy_adapter/core/settings.py +260 -0
- mcp_proxy_adapter/core/signal_handler.py +107 -0
- mcp_proxy_adapter/core/ssl_utils.py +161 -0
- mcp_proxy_adapter/core/transport_manager.py +153 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
- mcp_proxy_adapter/core/utils.py +101 -0
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +219 -0
- mcp_proxy_adapter/core/validation/file_validator.py +131 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
- mcp_proxy_adapter/core/validation/security_validator.py +140 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +58 -0
- mcp_proxy_adapter/examples/__init__.py +16 -0
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter/examples/check_config.py +413 -0
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/config_builder.py +234 -0
- mcp_proxy_adapter/examples/config_cli.py +282 -0
- mcp_proxy_adapter/examples/create_test_configs.py +174 -0
- mcp_proxy_adapter/examples/debug_request_state.py +130 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
- mcp_proxy_adapter/examples/demo_client.py +287 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
- mcp_proxy_adapter/examples/full_application/main.py +311 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
- mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
- mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
- mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
- mcp_proxy_adapter/examples/generate_config.py +502 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
- 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 +208 -0
- mcp_proxy_adapter/examples/run_example.py +77 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
- 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 +72 -0
- 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 +235 -0
- mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
- mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
- mcp_proxy_adapter/examples/test_config.py +205 -0
- mcp_proxy_adapter/examples/test_config_builder.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +308 -0
- mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
- mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
- mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
- mcp_proxy_adapter/examples/universal_client.py +674 -0
- mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +311 -0
- mcp_proxy_adapter/openapi.py +375 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/schemas/roles.json +37 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/version.py +5 -0
- mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
- mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
- {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
- mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
- mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
- adapters/__init__.py +0 -16
- analyzers/__init__.py +0 -14
- analyzers/docstring_analyzer.py +0 -199
- analyzers/type_analyzer.py +0 -151
- cli/__init__.py +0 -12
- cli/__main__.py +0 -79
- cli/command_runner.py +0 -233
- dispatchers/__init__.py +0 -14
- dispatchers/base_dispatcher.py +0 -85
- dispatchers/json_rpc_dispatcher.py +0 -198
- generators/__init__.py +0 -14
- generators/endpoint_generator.py +0 -172
- generators/openapi_generator.py +0 -254
- generators/rest_api_generator.py +0 -207
- mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
- mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
- mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
- mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
- openapi_schema/__init__.py +0 -38
- openapi_schema/command_registry.py +0 -312
- openapi_schema/rest_schema.py +0 -510
- openapi_schema/rpc_generator.py +0 -307
- openapi_schema/rpc_schema.py +0 -416
- validators/__init__.py +0 -14
- validators/base_validator.py +0 -23
- validators/docstring_validator.py +0 -75
- validators/metadata_validator.py +0 -76
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"""
|
|
2
|
+
mTLS Proxy for MCP Proxy Adapter
|
|
3
|
+
|
|
4
|
+
This module provides mTLS proxy functionality that accepts mTLS connections
|
|
5
|
+
and proxies them to the internal hypercorn server.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import ssl
|
|
13
|
+
import logging
|
|
14
|
+
from typing import Optional, Dict, Any
|
|
15
|
+
|
|
16
|
+
from .logging import get_global_logger
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MTLSProxy:
|
|
22
|
+
"""
|
|
23
|
+
mTLS Proxy that accepts mTLS connections and proxies them to internal server.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
external_host: str,
|
|
29
|
+
external_port: int,
|
|
30
|
+
internal_host: str = "127.0.0.1",
|
|
31
|
+
internal_port: int = 9000,
|
|
32
|
+
cert_file: Optional[str] = None,
|
|
33
|
+
key_file: Optional[str] = None,
|
|
34
|
+
ca_cert: Optional[str] = None,
|
|
35
|
+
):
|
|
36
|
+
"""
|
|
37
|
+
Initialize mTLS Proxy.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
external_host: External host to bind to
|
|
41
|
+
external_port: External port to bind to
|
|
42
|
+
internal_host: Internal server host
|
|
43
|
+
internal_port: Internal server port
|
|
44
|
+
cert_file: Server certificate file
|
|
45
|
+
key_file: Server private key file
|
|
46
|
+
ca_cert: CA certificate file for client verification
|
|
47
|
+
"""
|
|
48
|
+
self.external_host = external_host
|
|
49
|
+
self.external_port = external_port
|
|
50
|
+
self.internal_host = internal_host
|
|
51
|
+
self.internal_port = internal_port
|
|
52
|
+
self.cert_file = cert_file
|
|
53
|
+
self.key_file = key_file
|
|
54
|
+
self.ca_cert = ca_cert
|
|
55
|
+
self.server = None
|
|
56
|
+
|
|
57
|
+
async def start(self):
|
|
58
|
+
"""Start the mTLS proxy server."""
|
|
59
|
+
try:
|
|
60
|
+
# Create SSL context
|
|
61
|
+
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
|
62
|
+
ssl_context.load_cert_chain(self.cert_file, self.key_file)
|
|
63
|
+
|
|
64
|
+
if self.ca_cert:
|
|
65
|
+
ssl_context.load_verify_locations(self.ca_cert)
|
|
66
|
+
ssl_context.verify_mode = ssl.CERT_REQUIRED
|
|
67
|
+
else:
|
|
68
|
+
ssl_context.verify_mode = ssl.CERT_NONE
|
|
69
|
+
|
|
70
|
+
# Start server
|
|
71
|
+
self.server = await asyncio.start_server(
|
|
72
|
+
self._handle_client,
|
|
73
|
+
self.external_host,
|
|
74
|
+
self.external_port,
|
|
75
|
+
ssl=ssl_context,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
get_global_logger().info(
|
|
79
|
+
f"🔐 mTLS Proxy started on {self.external_host}:{self.external_port}"
|
|
80
|
+
)
|
|
81
|
+
get_global_logger().info(
|
|
82
|
+
f"🌐 Proxying to {self.internal_host}:{self.internal_port}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
except Exception as e:
|
|
86
|
+
get_global_logger().error(f"❌ Failed to start mTLS proxy: {e}")
|
|
87
|
+
raise
|
|
88
|
+
|
|
89
|
+
async def _proxy_data(self, reader, writer, direction):
|
|
90
|
+
"""Proxy data between reader and writer."""
|
|
91
|
+
try:
|
|
92
|
+
while True:
|
|
93
|
+
data = await reader.read(4096)
|
|
94
|
+
if not data:
|
|
95
|
+
break
|
|
96
|
+
writer.write(data)
|
|
97
|
+
await writer.drain()
|
|
98
|
+
except Exception as e:
|
|
99
|
+
get_global_logger().debug(f"Proxy connection closed ({direction}): {e}")
|
|
100
|
+
finally:
|
|
101
|
+
try:
|
|
102
|
+
writer.close()
|
|
103
|
+
await writer.wait_closed()
|
|
104
|
+
except Exception:
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
async def _handle_client(self, reader, writer):
|
|
108
|
+
"""
|
|
109
|
+
Handle incoming client connection.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
reader: Client reader stream
|
|
113
|
+
writer: Client writer stream
|
|
114
|
+
"""
|
|
115
|
+
internal_reader = None
|
|
116
|
+
internal_writer = None
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
# Connect to internal server
|
|
120
|
+
internal_reader, internal_writer = await asyncio.open_connection(
|
|
121
|
+
self.internal_host, self.internal_port
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Create bidirectional proxy tasks
|
|
125
|
+
client_to_server = asyncio.create_task(
|
|
126
|
+
self._proxy_data(reader, internal_writer, "client->server")
|
|
127
|
+
)
|
|
128
|
+
server_to_client = asyncio.create_task(
|
|
129
|
+
self._proxy_data(internal_reader, writer, "server->client")
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Wait for either direction to complete
|
|
133
|
+
done, pending = await asyncio.wait(
|
|
134
|
+
[client_to_server, server_to_client],
|
|
135
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Cancel pending tasks
|
|
139
|
+
for task in pending:
|
|
140
|
+
task.cancel()
|
|
141
|
+
|
|
142
|
+
# Wait for cancellation
|
|
143
|
+
await asyncio.gather(*pending, return_exceptions=True)
|
|
144
|
+
|
|
145
|
+
except Exception as e:
|
|
146
|
+
get_global_logger().debug(f"Client connection error: {e}")
|
|
147
|
+
finally:
|
|
148
|
+
# Clean up connections
|
|
149
|
+
if internal_writer:
|
|
150
|
+
try:
|
|
151
|
+
internal_writer.close()
|
|
152
|
+
await internal_writer.wait_closed()
|
|
153
|
+
except Exception:
|
|
154
|
+
pass
|
|
155
|
+
if writer:
|
|
156
|
+
try:
|
|
157
|
+
writer.close()
|
|
158
|
+
await writer.wait_closed()
|
|
159
|
+
except Exception:
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
async def start_mtls_proxy(
|
|
164
|
+
config: Dict[str, Any], internal_port: Optional[int] = None
|
|
165
|
+
) -> Optional[MTLSProxy]:
|
|
166
|
+
"""
|
|
167
|
+
Start mTLS proxy from configuration.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
config: Configuration dictionary
|
|
171
|
+
internal_port: Internal server port (hypercorn port). If not provided,
|
|
172
|
+
will be calculated as external_port + 1000
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
MTLSProxy instance if started successfully, None otherwise
|
|
176
|
+
"""
|
|
177
|
+
try:
|
|
178
|
+
server_config = config.get("server", {})
|
|
179
|
+
transport_config = config.get("transport", {})
|
|
180
|
+
ssl_config = config.get("ssl", {})
|
|
181
|
+
|
|
182
|
+
# Get external host and port
|
|
183
|
+
external_host = server_config.get("host", "0.0.0.0")
|
|
184
|
+
external_port = server_config.get("port", 8001)
|
|
185
|
+
|
|
186
|
+
# Get internal port (use provided or calculate)
|
|
187
|
+
if internal_port is None:
|
|
188
|
+
internal_port = external_port + 1000
|
|
189
|
+
|
|
190
|
+
# Get certificate paths - try multiple locations
|
|
191
|
+
cert_file = (
|
|
192
|
+
ssl_config.get("cert_file")
|
|
193
|
+
or transport_config.get("ssl", {}).get("cert_file")
|
|
194
|
+
or transport_config.get("cert_file")
|
|
195
|
+
)
|
|
196
|
+
key_file = (
|
|
197
|
+
ssl_config.get("key_file")
|
|
198
|
+
or transport_config.get("ssl", {}).get("key_file")
|
|
199
|
+
or transport_config.get("key_file")
|
|
200
|
+
)
|
|
201
|
+
ca_cert = (
|
|
202
|
+
ssl_config.get("ca_cert")
|
|
203
|
+
or transport_config.get("ssl", {}).get("ca_cert")
|
|
204
|
+
or transport_config.get("ca_cert")
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
if not cert_file or not key_file:
|
|
208
|
+
get_global_logger().warning(
|
|
209
|
+
"mTLS certificates not found, skipping mTLS proxy"
|
|
210
|
+
)
|
|
211
|
+
return None
|
|
212
|
+
|
|
213
|
+
# Create and start proxy
|
|
214
|
+
proxy = MTLSProxy(
|
|
215
|
+
external_host=external_host,
|
|
216
|
+
external_port=external_port,
|
|
217
|
+
internal_host="127.0.0.1",
|
|
218
|
+
internal_port=internal_port,
|
|
219
|
+
cert_file=cert_file,
|
|
220
|
+
key_file=key_file,
|
|
221
|
+
ca_cert=ca_cert,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
await proxy.start()
|
|
225
|
+
return proxy
|
|
226
|
+
|
|
227
|
+
except Exception as e:
|
|
228
|
+
get_global_logger().error(f"Failed to start mTLS proxy: {e}")
|
|
229
|
+
return None
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
mTLS Server implementation using built-in http.server.
|
|
4
|
+
|
|
5
|
+
Author: Vasiliy Zdanovskiy
|
|
6
|
+
email: vasilyvz@gmail.com
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import threading
|
|
10
|
+
import ssl
|
|
11
|
+
import json
|
|
12
|
+
import logging
|
|
13
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
14
|
+
from typing import Optional, Dict, Any
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class mTLSHandler(BaseHTTPRequestHandler):
|
|
21
|
+
"""Handler for mTLS connections."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, *args, main_app=None, **kwargs):
|
|
24
|
+
self.main_app = main_app
|
|
25
|
+
super().__init__(*args, **kwargs)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _forward_to_main_app(
|
|
31
|
+
self,
|
|
32
|
+
method: str,
|
|
33
|
+
path: str,
|
|
34
|
+
client_cert: Optional[Dict],
|
|
35
|
+
post_data: Optional[bytes] = None,
|
|
36
|
+
) -> Dict[str, Any]:
|
|
37
|
+
"""Forward request to main FastAPI application."""
|
|
38
|
+
try:
|
|
39
|
+
# This is a simplified forwarding - in real implementation
|
|
40
|
+
# you would use httpx or similar to make internal HTTP calls
|
|
41
|
+
# to the main FastAPI app running on different port
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
"status": "ok",
|
|
45
|
+
"message": f"mTLS {method} forwarded to main app",
|
|
46
|
+
"client_cert": client_cert,
|
|
47
|
+
"path": path,
|
|
48
|
+
"forwarded": True,
|
|
49
|
+
}
|
|
50
|
+
except Exception as e:
|
|
51
|
+
get_global_logger().error(f"Error forwarding to main app: {e}")
|
|
52
|
+
return {
|
|
53
|
+
"status": "error",
|
|
54
|
+
"message": f"Forwarding failed: {e}",
|
|
55
|
+
"client_cert": client_cert,
|
|
56
|
+
"path": path,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class mTLSServer:
|
|
61
|
+
"""mTLS Server using built-in http.server."""
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
host: str = "127.0.0.1",
|
|
66
|
+
port: int = 8443,
|
|
67
|
+
cert_file: str = None,
|
|
68
|
+
key_file: str = None,
|
|
69
|
+
ca_cert_file: str = None,
|
|
70
|
+
main_app=None,
|
|
71
|
+
):
|
|
72
|
+
"""
|
|
73
|
+
Initialize mTLS server.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
host: Server host
|
|
77
|
+
port: Server port
|
|
78
|
+
cert_file: Server certificate file
|
|
79
|
+
key_file: Server private key file
|
|
80
|
+
ca_cert_file: CA certificate file for client verification
|
|
81
|
+
main_app: Main FastAPI application for forwarding requests
|
|
82
|
+
"""
|
|
83
|
+
self.host = host
|
|
84
|
+
self.port = port
|
|
85
|
+
self.cert_file = cert_file
|
|
86
|
+
self.key_file = key_file
|
|
87
|
+
self.ca_cert_file = ca_cert_file
|
|
88
|
+
self.main_app = main_app
|
|
89
|
+
|
|
90
|
+
self.server: Optional[HTTPServer] = None
|
|
91
|
+
self.server_thread: Optional[threading.Thread] = None
|
|
92
|
+
self.running = False
|
|
93
|
+
|
|
94
|
+
get_global_logger().info(f"mTLS Server initialized: {host}:{port}")
|
|
95
|
+
|
|
96
|
+
def _create_handler(self):
|
|
97
|
+
"""Create handler with main app reference."""
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
return handler
|
|
101
|
+
|
|
102
|
+
def start(self) -> bool:
|
|
103
|
+
"""Start mTLS server in separate thread."""
|
|
104
|
+
try:
|
|
105
|
+
# Check if certificate files exist
|
|
106
|
+
if not os.path.exists(self.cert_file):
|
|
107
|
+
get_global_logger().error(f"Certificate file not found: {self.cert_file}")
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
if not os.path.exists(self.key_file):
|
|
111
|
+
get_global_logger().error(f"Key file not found: {self.key_file}")
|
|
112
|
+
return False
|
|
113
|
+
|
|
114
|
+
if not os.path.exists(self.ca_cert_file):
|
|
115
|
+
get_global_logger().error(
|
|
116
|
+
f"CA certificate file not found: {self.ca_cert_file}"
|
|
117
|
+
)
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
# Create server
|
|
121
|
+
handler_class = self._create_handler()
|
|
122
|
+
self.server = HTTPServer((self.host, self.port), handler_class)
|
|
123
|
+
|
|
124
|
+
# Configure SSL context
|
|
125
|
+
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
|
126
|
+
context.load_cert_chain(self.cert_file, self.key_file)
|
|
127
|
+
context.load_verify_locations(self.ca_cert_file)
|
|
128
|
+
context.verify_mode = ssl.CERT_REQUIRED
|
|
129
|
+
|
|
130
|
+
# Wrap socket with SSL
|
|
131
|
+
self.server.socket = context.wrap_socket(
|
|
132
|
+
self.server.socket, server_side=True
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Start server in separate thread
|
|
136
|
+
self.server_thread = threading.Thread(
|
|
137
|
+
target=self._run_server, daemon=True
|
|
138
|
+
)
|
|
139
|
+
self.server_thread.start()
|
|
140
|
+
|
|
141
|
+
self.running = True
|
|
142
|
+
get_global_logger().info(
|
|
143
|
+
f"✅ mTLS Server started on https://{self.host}:{self.port}"
|
|
144
|
+
)
|
|
145
|
+
return True
|
|
146
|
+
|
|
147
|
+
except Exception as e:
|
|
148
|
+
get_global_logger().error(f"Failed to start mTLS server: {e}")
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Protocol management module for MCP Proxy Adapter.
|
|
3
|
+
|
|
4
|
+
This module provides functionality for managing and validating protocol configurations,
|
|
5
|
+
including HTTP, HTTPS, and MTLS protocols with their respective ports.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import ssl
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
from typing import Dict, List, Any, Optional
|
|
11
|
+
|
|
12
|
+
from mcp_proxy_adapter.config import config
|
|
13
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ProtocolManager:
|
|
17
|
+
"""
|
|
18
|
+
Manages protocol configurations and validates protocol access.
|
|
19
|
+
|
|
20
|
+
This class handles the validation of allowed protocols and their associated ports,
|
|
21
|
+
ensuring that only configured protocols are accessible.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, app_config: Optional[Dict] = None):
|
|
25
|
+
"""
|
|
26
|
+
Initialize the protocol manager.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
app_config: Application configuration dictionary (optional)
|
|
30
|
+
"""
|
|
31
|
+
self.app_config = app_config
|
|
32
|
+
self._load_config()
|
|
33
|
+
|
|
34
|
+
def _load_config(self):
|
|
35
|
+
"""Load protocol configuration from config."""
|
|
36
|
+
# Use provided config or fallback to global config; normalize types
|
|
37
|
+
current_config = (
|
|
38
|
+
self.app_config if self.app_config is not None else config.get_all()
|
|
39
|
+
)
|
|
40
|
+
get_global_logger().debug(
|
|
41
|
+
f"ProtocolManager._load_config - current_config type: {type(current_config)}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if not hasattr(current_config, "get"):
|
|
45
|
+
# Not a dict-like config, fallback to global
|
|
46
|
+
get_global_logger().debug(
|
|
47
|
+
f"ProtocolManager._load_config - current_config is not dict-like, falling back to global config"
|
|
48
|
+
)
|
|
49
|
+
current_config = config.get_all()
|
|
50
|
+
|
|
51
|
+
get_global_logger().debug(
|
|
52
|
+
f"ProtocolManager._load_config - final current_config type: {type(current_config)}"
|
|
53
|
+
)
|
|
54
|
+
if hasattr(current_config, "get"):
|
|
55
|
+
get_global_logger().debug(
|
|
56
|
+
f"ProtocolManager._load_config - current_config keys: {list(current_config.keys()) if hasattr(current_config, 'keys') else 'no keys'}"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Get server protocol configuration (new simplified structure)
|
|
60
|
+
get_global_logger().debug(f"ProtocolManager._load_config - before getting server protocol")
|
|
61
|
+
try:
|
|
62
|
+
server_config = current_config.get("server", {})
|
|
63
|
+
server_protocol = server_config.get("protocol", "http")
|
|
64
|
+
get_global_logger().debug(f"ProtocolManager._load_config - server protocol: {server_protocol}")
|
|
65
|
+
|
|
66
|
+
# Set allowed protocols based on server protocol
|
|
67
|
+
if server_protocol == "http":
|
|
68
|
+
self.allowed_protocols = ["http"]
|
|
69
|
+
elif server_protocol == "https":
|
|
70
|
+
self.allowed_protocols = ["https"]
|
|
71
|
+
elif server_protocol == "mtls":
|
|
72
|
+
self.allowed_protocols = ["mtls", "https"] # mTLS also supports HTTPS
|
|
73
|
+
else:
|
|
74
|
+
# Fallback to HTTP
|
|
75
|
+
self.allowed_protocols = ["http"]
|
|
76
|
+
get_global_logger().warning(f"Unknown server protocol '{server_protocol}', defaulting to HTTP")
|
|
77
|
+
|
|
78
|
+
get_global_logger().debug(f"ProtocolManager._load_config - allowed protocols: {self.allowed_protocols}")
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
get_global_logger().debug(f"ProtocolManager._load_config - ERROR getting server protocol: {e}")
|
|
82
|
+
# Fallback to HTTP
|
|
83
|
+
self.allowed_protocols = ["http"]
|
|
84
|
+
|
|
85
|
+
# Protocol management is always enabled in new structure
|
|
86
|
+
self.enabled = True
|
|
87
|
+
|
|
88
|
+
get_global_logger().debug(
|
|
89
|
+
f"Protocol manager loaded config: enabled={self.enabled}, allowed_protocols={self.allowed_protocols}"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def is_protocol_allowed(self, protocol: str) -> bool:
|
|
96
|
+
"""
|
|
97
|
+
Check if a protocol is allowed based on configuration.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
protocol: Protocol name (http, https, mtls)
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
True if protocol is allowed, False otherwise
|
|
104
|
+
"""
|
|
105
|
+
get_global_logger().debug(f"🔍 ProtocolManager.is_protocol_allowed - protocol: {protocol}")
|
|
106
|
+
get_global_logger().debug(f"🔍 ProtocolManager.is_protocol_allowed - enabled: {self.enabled}")
|
|
107
|
+
get_global_logger().debug(f"🔍 ProtocolManager.is_protocol_allowed - allowed_protocols: {self.allowed_protocols}")
|
|
108
|
+
|
|
109
|
+
if not self.enabled:
|
|
110
|
+
get_global_logger().debug("✅ ProtocolManager.is_protocol_allowed - Protocol management is disabled, allowing all protocols")
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
protocol_lower = protocol.lower()
|
|
114
|
+
is_allowed = protocol_lower in self.allowed_protocols
|
|
115
|
+
|
|
116
|
+
get_global_logger().debug(f"🔍 ProtocolManager.is_protocol_allowed - Protocol '{protocol}' allowed: {is_allowed}")
|
|
117
|
+
return is_allowed
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def get_protocol_config(self, protocol: str) -> Dict:
|
|
122
|
+
"""
|
|
123
|
+
Get full configuration for a specific protocol.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
protocol: Protocol name (http, https, mtls)
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
Protocol configuration dictionary
|
|
130
|
+
"""
|
|
131
|
+
protocol_lower = protocol.lower()
|
|
132
|
+
cfg = self.protocols_config.get(protocol_lower, {})
|
|
133
|
+
# Ensure dict type
|
|
134
|
+
if isinstance(cfg, dict):
|
|
135
|
+
try:
|
|
136
|
+
return cfg.copy()
|
|
137
|
+
except Exception:
|
|
138
|
+
return {}
|
|
139
|
+
return {}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_ssl_context_for_protocol(self, protocol: str) -> Optional[ssl.SSLContext]:
|
|
143
|
+
"""
|
|
144
|
+
Get SSL context for HTTPS or MTLS protocol.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
protocol: Protocol name (https, mtls)
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
SSL context if protocol requires SSL, None otherwise
|
|
151
|
+
"""
|
|
152
|
+
if protocol.lower() not in ["https", "mtls"]:
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
# Use provided config or fallback to global config
|
|
156
|
+
current_config = (
|
|
157
|
+
self.app_config if self.app_config is not None else config.get_all()
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Get SSL configuration
|
|
161
|
+
ssl_config = self._get_ssl_config(current_config)
|
|
162
|
+
|
|
163
|
+
if not ssl_config.get("enabled", False):
|
|
164
|
+
get_global_logger().warning(
|
|
165
|
+
f"SSL required for protocol '{protocol}' but SSL is disabled"
|
|
166
|
+
)
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
cert_file = ssl_config.get("cert_file")
|
|
170
|
+
key_file = ssl_config.get("key_file")
|
|
171
|
+
|
|
172
|
+
if not cert_file or not key_file:
|
|
173
|
+
get_global_logger().warning(
|
|
174
|
+
f"SSL required for protocol '{protocol}' but certificate files not configured"
|
|
175
|
+
)
|
|
176
|
+
return None
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
from mcp_proxy_adapter.core.ssl_utils import SSLUtils
|
|
180
|
+
|
|
181
|
+
ssl_context = SSLUtils.create_ssl_context(
|
|
182
|
+
cert_file=cert_file,
|
|
183
|
+
key_file=key_file,
|
|
184
|
+
ca_cert=ssl_config.get("ca_cert"),
|
|
185
|
+
verify_client=protocol.lower() == "mtls"
|
|
186
|
+
or ssl_config.get("verify_client", False),
|
|
187
|
+
cipher_suites=ssl_config.get("cipher_suites", []),
|
|
188
|
+
min_tls_version=ssl_config.get("min_tls_version", "1.2"),
|
|
189
|
+
max_tls_version=ssl_config.get("max_tls_version", "1.3"),
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
get_global_logger().info(f"SSL context created for protocol '{protocol}'")
|
|
193
|
+
return ssl_context
|
|
194
|
+
|
|
195
|
+
except Exception as e:
|
|
196
|
+
get_global_logger().error(f"Failed to create SSL context for protocol '{protocol}': {e}")
|
|
197
|
+
return None
|
|
198
|
+
|
|
199
|
+
def _get_ssl_config(self, current_config: Dict) -> Dict:
|
|
200
|
+
"""
|
|
201
|
+
Get SSL configuration from config.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
current_config: Current configuration dictionary
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
SSL configuration dictionary
|
|
208
|
+
"""
|
|
209
|
+
# Try security framework SSL config first
|
|
210
|
+
security_config = current_config.get("security", {})
|
|
211
|
+
ssl_config = security_config.get("ssl", {})
|
|
212
|
+
|
|
213
|
+
if ssl_config.get("enabled", False):
|
|
214
|
+
get_global_logger().debug("Using security.ssl configuration")
|
|
215
|
+
return ssl_config
|
|
216
|
+
|
|
217
|
+
# Fallback to legacy SSL config
|
|
218
|
+
legacy_ssl_config = current_config.get("ssl", {})
|
|
219
|
+
if legacy_ssl_config.get("enabled", False):
|
|
220
|
+
get_global_logger().debug("Using legacy ssl configuration")
|
|
221
|
+
return legacy_ssl_config
|
|
222
|
+
|
|
223
|
+
# Return empty config if SSL is disabled
|
|
224
|
+
return {"enabled": False}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
# Global protocol manager instance - will be updated with config when needed
|
|
230
|
+
protocol_manager = None
|
|
231
|
+
|
|
232
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ProxyRegistrationManager",
|
|
15
|
+
"ProxyRegistrationError",
|
|
16
|
+
"AuthManager",
|
|
17
|
+
"SSLManager",
|
|
18
|
+
"RegistrationClient",
|
|
19
|
+
]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Authentication management for proxy registration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, Any
|
|
9
|
+
|
|
10
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AuthManager:
|
|
14
|
+
"""Manager for authentication in proxy registration."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, client_security, registration_config: Dict[str, Any]):
|
|
17
|
+
"""
|
|
18
|
+
Initialize authentication manager.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
client_security: Client security manager instance
|
|
22
|
+
registration_config: Registration configuration
|
|
23
|
+
"""
|
|
24
|
+
self.client_security = client_security
|
|
25
|
+
self.registration_config = registration_config
|
|
26
|
+
self.logger = get_global_logger()
|