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,105 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
CLI command: config generate (Simple configuration generator)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import sys
|
|
12
|
+
from argparse import Namespace
|
|
13
|
+
|
|
14
|
+
from mcp_proxy_adapter.core.config.simple_config_generator import SimpleConfigGenerator
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def config_generate_command(args: Namespace) -> int:
|
|
18
|
+
generator = SimpleConfigGenerator()
|
|
19
|
+
out = generator.generate(
|
|
20
|
+
protocol=args.protocol,
|
|
21
|
+
with_proxy=args.with_proxy,
|
|
22
|
+
out_path=args.out,
|
|
23
|
+
# Server parameters
|
|
24
|
+
server_host=getattr(args, "server_host", None),
|
|
25
|
+
server_port=getattr(args, "server_port", None),
|
|
26
|
+
server_cert_file=getattr(args, "server_cert_file", None),
|
|
27
|
+
server_key_file=getattr(args, "server_key_file", None),
|
|
28
|
+
server_ca_cert_file=getattr(args, "server_ca_cert_file", None),
|
|
29
|
+
server_crl_file=getattr(args, "server_crl_file", None),
|
|
30
|
+
# Client parameters
|
|
31
|
+
client_enabled=getattr(args, "client_enabled", False),
|
|
32
|
+
client_protocol=getattr(args, "client_protocol", None),
|
|
33
|
+
client_cert_file=getattr(args, "client_cert_file", None),
|
|
34
|
+
client_key_file=getattr(args, "client_key_file", None),
|
|
35
|
+
client_ca_cert_file=getattr(args, "client_ca_cert_file", None),
|
|
36
|
+
client_crl_file=getattr(args, "client_crl_file", None),
|
|
37
|
+
# Registration parameters
|
|
38
|
+
registration_host=getattr(args, "registration_host", None),
|
|
39
|
+
registration_port=getattr(args, "registration_port", None),
|
|
40
|
+
registration_protocol=getattr(args, "registration_protocol", None),
|
|
41
|
+
registration_cert_file=getattr(args, "registration_cert_file", None),
|
|
42
|
+
registration_key_file=getattr(args, "registration_key_file", None),
|
|
43
|
+
registration_ca_cert_file=getattr(args, "registration_ca_cert_file", None),
|
|
44
|
+
registration_crl_file=getattr(args, "registration_crl_file", None),
|
|
45
|
+
)
|
|
46
|
+
print(f"✅ Configuration generated: {out}")
|
|
47
|
+
return 0
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> int:
|
|
51
|
+
"""Main entry point for adapter-cfg-gen CLI command."""
|
|
52
|
+
parser = argparse.ArgumentParser(
|
|
53
|
+
prog="adapter-cfg-gen",
|
|
54
|
+
description="Generate simple configuration file for MCP Proxy Adapter"
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
'--protocol',
|
|
58
|
+
required=True,
|
|
59
|
+
choices=['http', 'https', 'mtls'],
|
|
60
|
+
help='Server/proxy protocol'
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
'--with-proxy',
|
|
64
|
+
action='store_true',
|
|
65
|
+
help='Enable proxy registration (deprecated, use --registration-* parameters)'
|
|
66
|
+
)
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
'--out',
|
|
69
|
+
default='config.json',
|
|
70
|
+
help='Output config path (default: config.json)'
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Server parameters
|
|
74
|
+
parser.add_argument('--server-host', help='Server host (default: 0.0.0.0)')
|
|
75
|
+
parser.add_argument('--server-port', type=int, help='Server port (default: 8080)')
|
|
76
|
+
parser.add_argument('--server-cert-file', help='Server certificate file path')
|
|
77
|
+
parser.add_argument('--server-key-file', help='Server key file path')
|
|
78
|
+
parser.add_argument('--server-ca-cert-file', help='Server CA certificate file path')
|
|
79
|
+
parser.add_argument('--server-crl-file', help='Server CRL file path')
|
|
80
|
+
|
|
81
|
+
# Client parameters
|
|
82
|
+
parser.add_argument('--client-enabled', action='store_true', help='Enable client configuration')
|
|
83
|
+
parser.add_argument('--client-protocol', choices=['http', 'https', 'mtls'], help='Client protocol')
|
|
84
|
+
parser.add_argument('--client-cert-file', help='Client certificate file path')
|
|
85
|
+
parser.add_argument('--client-key-file', help='Client key file path')
|
|
86
|
+
parser.add_argument('--client-ca-cert-file', help='Client CA certificate file path')
|
|
87
|
+
parser.add_argument('--client-crl-file', help='Client CRL file path')
|
|
88
|
+
|
|
89
|
+
# Registration parameters
|
|
90
|
+
parser.add_argument('--registration-host', help='Registration proxy host (default: localhost)')
|
|
91
|
+
parser.add_argument('--registration-port', type=int, help='Registration proxy port (default: 3005)')
|
|
92
|
+
parser.add_argument('--registration-protocol', choices=['http', 'https', 'mtls'], help='Registration protocol')
|
|
93
|
+
parser.add_argument('--registration-cert-file', help='Registration certificate file path')
|
|
94
|
+
parser.add_argument('--registration-key-file', help='Registration key file path')
|
|
95
|
+
parser.add_argument('--registration-ca-cert-file', help='Registration CA certificate file path')
|
|
96
|
+
parser.add_argument('--registration-crl-file', help='Registration CRL file path')
|
|
97
|
+
|
|
98
|
+
args = parser.parse_args()
|
|
99
|
+
return config_generate_command(args)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
sys.exit(main())
|
|
104
|
+
|
|
105
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
CLI command: config validate (Configuration validation)
|
|
6
|
+
Supports both SimpleConfig and full configuration formats.
|
|
7
|
+
Uses the same ConfigValidator as server startup.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import json
|
|
14
|
+
import sys
|
|
15
|
+
from argparse import Namespace
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from mcp_proxy_adapter.core.validation.config_validator import ConfigValidator
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def config_validate_command(args: Namespace) -> int:
|
|
22
|
+
"""
|
|
23
|
+
Validate configuration file using ConfigValidator.
|
|
24
|
+
|
|
25
|
+
This uses the same validator as server startup to ensure consistency.
|
|
26
|
+
"""
|
|
27
|
+
config_file = Path(args.file)
|
|
28
|
+
|
|
29
|
+
if not config_file.exists():
|
|
30
|
+
print(f"❌ Configuration file not found: {config_file}")
|
|
31
|
+
return 1
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
# Load configuration
|
|
35
|
+
with open(config_file, 'r', encoding='utf-8') as f:
|
|
36
|
+
config_data = json.load(f)
|
|
37
|
+
except json.JSONDecodeError as e:
|
|
38
|
+
print(f"❌ Invalid JSON in configuration file: {e}")
|
|
39
|
+
return 1
|
|
40
|
+
except Exception as e:
|
|
41
|
+
print(f"❌ Failed to load config: {e}")
|
|
42
|
+
return 1
|
|
43
|
+
|
|
44
|
+
# Use the same ConfigValidator as server startup
|
|
45
|
+
validator = ConfigValidator(config_path=str(config_file))
|
|
46
|
+
validator.config_data = config_data
|
|
47
|
+
validation_results = validator.validate_config()
|
|
48
|
+
|
|
49
|
+
# Separate errors and warnings
|
|
50
|
+
errors = [r for r in validation_results if r.level == "error"]
|
|
51
|
+
warnings = [r for r in validation_results if r.level == "warning"]
|
|
52
|
+
|
|
53
|
+
if errors:
|
|
54
|
+
print("❌ Validation failed:")
|
|
55
|
+
for err in errors:
|
|
56
|
+
section_info = f" ({err.section}" + (f".{err.key}" if err.key else "") + ")" if err.section else ""
|
|
57
|
+
print(f" - {err.message}{section_info}")
|
|
58
|
+
if warnings:
|
|
59
|
+
print("\n⚠️ Warnings:")
|
|
60
|
+
for warn in warnings:
|
|
61
|
+
section_info = f" ({warn.section}" + (f".{warn.key}" if warn.key else "") + ")" if warn.section else ""
|
|
62
|
+
print(f" - {warn.message}{section_info}")
|
|
63
|
+
return 1
|
|
64
|
+
|
|
65
|
+
if warnings:
|
|
66
|
+
print("✅ Validation passed with warnings:")
|
|
67
|
+
for warn in warnings:
|
|
68
|
+
section_info = f" ({warn.section}" + (f".{warn.key}" if warn.key else "") + ")" if warn.section else ""
|
|
69
|
+
print(f" ⚠️ {warn.message}{section_info}")
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
print("✅ Validation OK")
|
|
73
|
+
return 0
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def main() -> int:
|
|
77
|
+
"""Main entry point for adapter-cfg-val CLI command."""
|
|
78
|
+
parser = argparse.ArgumentParser(
|
|
79
|
+
prog="adapter-cfg-val",
|
|
80
|
+
description="Validate configuration file for MCP Proxy Adapter"
|
|
81
|
+
)
|
|
82
|
+
parser.add_argument(
|
|
83
|
+
'--file',
|
|
84
|
+
required=True,
|
|
85
|
+
help='Path to configuration file'
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
args = parser.parse_args()
|
|
89
|
+
return config_validate_command(args)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
sys.exit(main())
|
|
94
|
+
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generate Command
|
|
3
|
+
|
|
4
|
+
This module implements the generate command for creating configuration files.
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Dict, Any, Optional
|
|
13
|
+
|
|
14
|
+
# Import the existing config generator
|
|
15
|
+
try:
|
|
16
|
+
from mcp_proxy_adapter.examples.config_builder import generate_complete_config
|
|
17
|
+
from mcp_proxy_adapter.core.config_validator import ConfigValidator
|
|
18
|
+
VALIDATION_AVAILABLE = True
|
|
19
|
+
except ImportError:
|
|
20
|
+
VALIDATION_AVAILABLE = False
|
|
21
|
+
print("Warning: Configuration validation not available. Install the package to enable validation.")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GenerateCommand:
|
|
25
|
+
"""Command for generating configuration files."""
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""Initialize the generate command."""
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def execute(self, args: Dict[str, Any]) -> int:
|
|
32
|
+
"""
|
|
33
|
+
Execute the generate command.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
args: Parsed command arguments
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Exit code (0 for success, 1 for error)
|
|
40
|
+
"""
|
|
41
|
+
try:
|
|
42
|
+
# Handle special cases
|
|
43
|
+
if args.get('all'):
|
|
44
|
+
return self._generate_all_configs(args)
|
|
45
|
+
|
|
46
|
+
# Generate single configuration
|
|
47
|
+
return self._generate_single_config(args)
|
|
48
|
+
|
|
49
|
+
except Exception as e:
|
|
50
|
+
print(f"❌ Error generating configuration: {e}")
|
|
51
|
+
return 1
|
|
52
|
+
|
|
53
|
+
def _generate_single_config(self, args: Dict[str, Any]) -> int:
|
|
54
|
+
"""Generate a single configuration file."""
|
|
55
|
+
# Create configuration
|
|
56
|
+
config = self._create_config_from_args(args)
|
|
57
|
+
|
|
58
|
+
# Save configuration
|
|
59
|
+
if args.get('stdout'):
|
|
60
|
+
# Output to stdout
|
|
61
|
+
print(json.dumps(config, indent=2, ensure_ascii=False))
|
|
62
|
+
else:
|
|
63
|
+
# Save to file
|
|
64
|
+
config_file = self._save_config(config, args)
|
|
65
|
+
print(f"✅ Configuration saved to: {config_file}")
|
|
66
|
+
|
|
67
|
+
return 0
|
|
68
|
+
|
|
69
|
+
def _generate_all_configs(self, args: Dict[str, Any]) -> int:
|
|
70
|
+
"""Generate all standard configurations."""
|
|
71
|
+
print("🔧 Generating MCP Proxy Adapter configurations...")
|
|
72
|
+
print("=" * 60)
|
|
73
|
+
|
|
74
|
+
# Define all standard configurations
|
|
75
|
+
configs = [
|
|
76
|
+
# HTTP configurations
|
|
77
|
+
("http", False, False, 20000),
|
|
78
|
+
("http", True, True, 20001), # token + roles
|
|
79
|
+
("http", True, False, 20002), # token only
|
|
80
|
+
|
|
81
|
+
# HTTPS configurations
|
|
82
|
+
("https", False, False, 20003),
|
|
83
|
+
("https", True, True, 20004), # token + roles
|
|
84
|
+
("https", True, False, 20005), # token only
|
|
85
|
+
|
|
86
|
+
# mTLS configurations
|
|
87
|
+
("mtls", False, False, 20006),
|
|
88
|
+
("mtls", False, True, 20007), # roles only (from certificate)
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
generated_files = []
|
|
92
|
+
|
|
93
|
+
for protocol, token, roles, port in configs:
|
|
94
|
+
# Create configuration name
|
|
95
|
+
name_parts = [protocol]
|
|
96
|
+
if token:
|
|
97
|
+
name_parts.append("token")
|
|
98
|
+
if roles:
|
|
99
|
+
name_parts.append("roles")
|
|
100
|
+
|
|
101
|
+
config_name = "_".join(name_parts)
|
|
102
|
+
|
|
103
|
+
# Create args for this configuration
|
|
104
|
+
config_args = args.copy()
|
|
105
|
+
config_args.update({
|
|
106
|
+
'protocol': protocol,
|
|
107
|
+
'token': token,
|
|
108
|
+
'roles': roles,
|
|
109
|
+
'port': port
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
# Generate configuration
|
|
113
|
+
config = self._create_config_from_args(config_args)
|
|
114
|
+
|
|
115
|
+
# Save configuration
|
|
116
|
+
config_file = self._save_config(config, config_args, config_name)
|
|
117
|
+
generated_files.append(config_file)
|
|
118
|
+
|
|
119
|
+
print(f"✅ Created {config_name}.json (port {port})")
|
|
120
|
+
|
|
121
|
+
# Create roles.json file if any role-based configs were generated
|
|
122
|
+
self._create_roles_file(args.get('output_dir', './configs'))
|
|
123
|
+
|
|
124
|
+
print(f"\n🎉 Generated {len(generated_files)} configurations in {args.get('output_dir', './configs')}/")
|
|
125
|
+
print("\n📋 Generated configurations:")
|
|
126
|
+
for config_file in generated_files:
|
|
127
|
+
print(f" - {config_file.name}")
|
|
128
|
+
|
|
129
|
+
return 0
|
|
130
|
+
|
|
131
|
+
def _create_config_from_args(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
132
|
+
"""Create configuration dictionary from arguments."""
|
|
133
|
+
# Start with basic configuration
|
|
134
|
+
config = generate_complete_config(
|
|
135
|
+
args.get('host', '127.0.0.1'),
|
|
136
|
+
args.get('port', 8000)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Set protocol
|
|
140
|
+
config["server"]["protocol"] = args.get('protocol', 'http')
|
|
141
|
+
|
|
142
|
+
# Configure SSL based on protocol
|
|
143
|
+
if args.get('protocol') == 'https':
|
|
144
|
+
config["ssl"]["enabled"] = True
|
|
145
|
+
config["ssl"]["cert_file"] = f"{args.get('cert_dir', './certs')}/server.crt"
|
|
146
|
+
config["ssl"]["key_file"] = f"{args.get('key_dir', './keys')}/server.key"
|
|
147
|
+
elif args.get('protocol') == 'mtls':
|
|
148
|
+
config["ssl"]["enabled"] = True
|
|
149
|
+
config["ssl"]["cert_file"] = f"{args.get('cert_dir', './certs')}/server.crt"
|
|
150
|
+
config["ssl"]["key_file"] = f"{args.get('key_dir', './keys')}/server.key"
|
|
151
|
+
config["ssl"]["ca_cert"] = f"{args.get('cert_dir', './certs')}/ca.crt"
|
|
152
|
+
config["transport"]["verify_client"] = True
|
|
153
|
+
|
|
154
|
+
# Configure security if token authentication is enabled
|
|
155
|
+
if args.get('token'):
|
|
156
|
+
config["security"]["enabled"] = True
|
|
157
|
+
config["security"]["tokens"] = {
|
|
158
|
+
"admin": "admin-secret-key",
|
|
159
|
+
"user": "user-secret-key",
|
|
160
|
+
"readonly": "readonly-secret-key"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if args.get('roles'):
|
|
164
|
+
config["security"]["roles"] = {
|
|
165
|
+
"admin": ["read", "write", "delete", "admin"],
|
|
166
|
+
"user": ["read", "write"],
|
|
167
|
+
"readonly": ["read"]
|
|
168
|
+
}
|
|
169
|
+
config["security"]["roles_file"] = f"{args.get('output_dir', './configs')}/roles.json"
|
|
170
|
+
config["roles"]["enabled"] = True
|
|
171
|
+
config["roles"]["config_file"] = f"{args.get('output_dir', './configs')}/roles.json"
|
|
172
|
+
elif args.get('roles') and args.get('protocol') == 'mtls':
|
|
173
|
+
# For mTLS, roles can be enabled without tokens (from certificate)
|
|
174
|
+
config["roles"]["enabled"] = True
|
|
175
|
+
config["roles"]["config_file"] = f"{args.get('output_dir', './configs')}/roles.json"
|
|
176
|
+
|
|
177
|
+
# Configure proxy registration if enabled
|
|
178
|
+
if args.get('proxy_url'):
|
|
179
|
+
config["proxy_registration"]["enabled"] = True
|
|
180
|
+
config["proxy_registration"]["proxy_url"] = args['proxy_url']
|
|
181
|
+
config["proxy_registration"]["server_id"] = args.get('server_id', 'mcp-proxy-adapter')
|
|
182
|
+
|
|
183
|
+
return config
|
|
184
|
+
|
|
185
|
+
def _save_config(self, config: Dict[str, Any], args: Dict[str, Any], filename: Optional[str] = None) -> Path:
|
|
186
|
+
"""Save configuration to file with optional validation."""
|
|
187
|
+
output_dir = Path(args.get('output_dir', './configs'))
|
|
188
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
189
|
+
|
|
190
|
+
# Determine filename
|
|
191
|
+
if filename:
|
|
192
|
+
config_name = filename
|
|
193
|
+
elif args.get('output'):
|
|
194
|
+
config_name = args['output']
|
|
195
|
+
else:
|
|
196
|
+
# Generate filename from arguments
|
|
197
|
+
name_parts = [args.get('protocol', 'http')]
|
|
198
|
+
if args.get('token'):
|
|
199
|
+
name_parts.append("token")
|
|
200
|
+
if args.get('roles'):
|
|
201
|
+
name_parts.append("roles")
|
|
202
|
+
config_name = "_".join(name_parts)
|
|
203
|
+
|
|
204
|
+
config_file = output_dir / f"{config_name}.json"
|
|
205
|
+
|
|
206
|
+
# Save configuration
|
|
207
|
+
with open(config_file, 'w', encoding='utf-8') as f:
|
|
208
|
+
json.dump(config, f, indent=2, ensure_ascii=False)
|
|
209
|
+
|
|
210
|
+
# Validate configuration if requested and validation is available
|
|
211
|
+
if not args.get('no_validate') and VALIDATION_AVAILABLE:
|
|
212
|
+
print(f"🔍 Validating configuration: {config_file}")
|
|
213
|
+
validator = ConfigValidator()
|
|
214
|
+
validator.config_data = config
|
|
215
|
+
results = validator.validate_config()
|
|
216
|
+
|
|
217
|
+
if results:
|
|
218
|
+
print("⚠️ Validation issues found:")
|
|
219
|
+
for result in results:
|
|
220
|
+
level_symbol = "❌" if result.level == "error" else "⚠️" if result.level == "warning" else "ℹ️"
|
|
221
|
+
print(f" {level_symbol} {result.message}")
|
|
222
|
+
if hasattr(result, 'suggestion') and result.suggestion:
|
|
223
|
+
print(f" Suggestion: {result.suggestion}")
|
|
224
|
+
else:
|
|
225
|
+
print("✅ Configuration validation passed!")
|
|
226
|
+
|
|
227
|
+
return config_file
|
|
228
|
+
|
|
229
|
+
def _create_roles_file(self, output_dir: str) -> None:
|
|
230
|
+
"""Create roles.json file for role-based configurations."""
|
|
231
|
+
roles_config = {
|
|
232
|
+
"enabled": True,
|
|
233
|
+
"default_policy": {
|
|
234
|
+
"deny_by_default": False,
|
|
235
|
+
"require_role_match": False,
|
|
236
|
+
"case_sensitive": False,
|
|
237
|
+
"allow_wildcard": False
|
|
238
|
+
},
|
|
239
|
+
"roles": {
|
|
240
|
+
"admin": ["read", "write", "delete", "admin"],
|
|
241
|
+
"user": ["read", "write"],
|
|
242
|
+
"readonly": ["read"],
|
|
243
|
+
"guest": ["read"],
|
|
244
|
+
"proxy": ["read", "write"]
|
|
245
|
+
},
|
|
246
|
+
"permissions": {
|
|
247
|
+
"read": ["GET"],
|
|
248
|
+
"write": ["POST", "PUT", "PATCH"],
|
|
249
|
+
"delete": ["DELETE"],
|
|
250
|
+
"admin": ["*"]
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
roles_file = Path(output_dir) / "roles.json"
|
|
255
|
+
with open(roles_file, 'w', encoding='utf-8') as f:
|
|
256
|
+
json.dump(roles_config, f, indent=2, ensure_ascii=False)
|
|
257
|
+
print(f"✅ Created roles.json")
|
|
258
|
+
|
|
259
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Server Command
|
|
3
|
+
|
|
4
|
+
This module implements the server command for starting MCP Proxy Adapter server.
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Dict, Any
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
from mcp_proxy_adapter.core.validation.config_validator import ConfigValidator
|
|
16
|
+
from mcp_proxy_adapter.core.server_adapter import UnifiedServerRunner
|
|
17
|
+
from mcp_proxy_adapter.api.app import create_app
|
|
18
|
+
VALIDATION_AVAILABLE = True
|
|
19
|
+
except ImportError:
|
|
20
|
+
VALIDATION_AVAILABLE = False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ServerCommand:
|
|
24
|
+
"""Command for starting the MCP Proxy Adapter server."""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Initialize the server command."""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
def execute(self, args: Dict[str, Any]) -> int:
|
|
31
|
+
"""
|
|
32
|
+
Execute the server command.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
args: Parsed command arguments
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Exit code (0 for success, 1 for error)
|
|
39
|
+
"""
|
|
40
|
+
config_file = args['config']
|
|
41
|
+
no_validate = args.get('no_validate', False)
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
# Load configuration
|
|
45
|
+
print(f"🔍 Loading configuration from: {config_file}")
|
|
46
|
+
with open(config_file, 'r', encoding='utf-8') as f:
|
|
47
|
+
config = json.load(f)
|
|
48
|
+
|
|
49
|
+
# Validate configuration if not disabled
|
|
50
|
+
if not no_validate and VALIDATION_AVAILABLE:
|
|
51
|
+
print("🔍 Validating configuration...")
|
|
52
|
+
if not self._validate_config(config, config_file):
|
|
53
|
+
print("❌ Configuration validation failed. Server not started.")
|
|
54
|
+
return 1
|
|
55
|
+
print("✅ Configuration validation passed!")
|
|
56
|
+
elif no_validate:
|
|
57
|
+
print("⚠️ Configuration validation skipped (--no-validate)")
|
|
58
|
+
else:
|
|
59
|
+
print("⚠️ Configuration validation not available")
|
|
60
|
+
|
|
61
|
+
# Override configuration with command line arguments
|
|
62
|
+
if args.get('port'):
|
|
63
|
+
config['server']['port'] = args['port']
|
|
64
|
+
print(f"🔧 Overriding port to: {args['port']}")
|
|
65
|
+
|
|
66
|
+
if args.get('host'):
|
|
67
|
+
config['server']['host'] = args['host']
|
|
68
|
+
print(f"🔧 Overriding host to: {args['host']}")
|
|
69
|
+
|
|
70
|
+
# Create and start server
|
|
71
|
+
print("🚀 Starting MCP Proxy Adapter server...")
|
|
72
|
+
self._start_server(config, args)
|
|
73
|
+
|
|
74
|
+
except FileNotFoundError:
|
|
75
|
+
print(f"❌ Configuration file not found: {config_file}")
|
|
76
|
+
return 1
|
|
77
|
+
except json.JSONDecodeError as e:
|
|
78
|
+
print(f"❌ Invalid JSON in configuration file: {e}")
|
|
79
|
+
return 1
|
|
80
|
+
except Exception as e:
|
|
81
|
+
print(f"❌ Error starting server: {e}")
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
def _validate_config(self, config: Dict[str, Any], config_file: str) -> bool:
|
|
85
|
+
"""
|
|
86
|
+
Validate configuration using ConfigValidator.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
config: Configuration dictionary
|
|
90
|
+
config_file: Path to configuration file
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
True if configuration is valid, False otherwise
|
|
94
|
+
"""
|
|
95
|
+
try:
|
|
96
|
+
validator = ConfigValidator()
|
|
97
|
+
validator.config_data = config
|
|
98
|
+
results = validator.validate_config()
|
|
99
|
+
|
|
100
|
+
# Check for errors
|
|
101
|
+
errors = [r for r in results if r.level == "error"]
|
|
102
|
+
warnings = [r for r in results if r.level == "warning"]
|
|
103
|
+
|
|
104
|
+
if errors:
|
|
105
|
+
print("❌ Configuration validation errors:")
|
|
106
|
+
for error in errors:
|
|
107
|
+
print(f" • {error.message}")
|
|
108
|
+
if hasattr(error, 'suggestion') and error.suggestion:
|
|
109
|
+
print(f" → {error.suggestion}")
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
if warnings:
|
|
113
|
+
print("⚠️ Configuration validation warnings:")
|
|
114
|
+
for warning in warnings:
|
|
115
|
+
print(f" • {warning.message}")
|
|
116
|
+
if hasattr(warning, 'suggestion') and warning.suggestion:
|
|
117
|
+
print(f" → {warning.suggestion}")
|
|
118
|
+
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
except Exception as e:
|
|
122
|
+
print(f"❌ Error during configuration validation: {e}")
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
def _start_server(self, config: Dict[str, Any], args: Dict[str, Any]) -> None:
|
|
126
|
+
"""
|
|
127
|
+
Start the MCP Proxy Adapter server.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
config: Server configuration
|
|
131
|
+
args: Command line arguments
|
|
132
|
+
"""
|
|
133
|
+
try:
|
|
134
|
+
# Create ASGI application
|
|
135
|
+
app = create_app(config)
|
|
136
|
+
|
|
137
|
+
# Prepare server configuration
|
|
138
|
+
server_config = {
|
|
139
|
+
'host': config['server']['host'],
|
|
140
|
+
'port': config['server']['port'],
|
|
141
|
+
'log_level': config['server'].get('log_level', 'INFO'),
|
|
142
|
+
'reload': args.get('reload', False)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# Add SSL configuration if present
|
|
146
|
+
if 'ssl' in config and config['ssl'].get('enabled'):
|
|
147
|
+
server_config.update({
|
|
148
|
+
'certfile': config['ssl'].get('cert_file'),
|
|
149
|
+
'keyfile': config['ssl'].get('key_file'),
|
|
150
|
+
'ca_certs': config['ssl'].get('ca_cert'),
|
|
151
|
+
'verify_mode': 'CERT_REQUIRED' if config.get('transport', {}).get('verify_client') else 'CERT_NONE'
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
# Start server
|
|
155
|
+
print(f"🌐 Server starting on {server_config['host']}:{server_config['port']}")
|
|
156
|
+
print(f"📋 Protocol: {config['server']['protocol']}")
|
|
157
|
+
print(f"🔐 Security: {'Enabled' if config.get('security', {}).get('enabled') else 'Disabled'}")
|
|
158
|
+
print(f"🔑 Authentication: {'Token-based' if config.get('security', {}).get('tokens') else 'Certificate-based' if config['server']['protocol'] == 'mtls' else 'None'}")
|
|
159
|
+
print(f"👥 Roles: {'Enabled' if config.get('roles', {}).get('enabled') else 'Disabled'}")
|
|
160
|
+
print("=" * 60)
|
|
161
|
+
|
|
162
|
+
# Use UnifiedServerRunner to start the server
|
|
163
|
+
runner = UnifiedServerRunner()
|
|
164
|
+
runner.run_server(app, server_config)
|
|
165
|
+
|
|
166
|
+
except ImportError as e:
|
|
167
|
+
print(f"❌ Missing required dependencies: {e}")
|
|
168
|
+
print("💡 Install required packages: pip install hypercorn")
|
|
169
|
+
raise
|
|
170
|
+
except Exception as e:
|
|
171
|
+
print(f"❌ Failed to start server: {e}")
|
|
172
|
+
raise
|
|
173
|
+
|
|
174
|
+
|