mcp-proxy-adapter 6.9.28__py3-none-any.whl → 6.9.29__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 +0 -6
- 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.29.dist-info}/METADATA +2 -1
- mcp_proxy_adapter-6.9.29.dist-info/RECORD +235 -0
- {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.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.29.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sets Command
|
|
3
|
+
|
|
4
|
+
This module implements the sets command for generating configurations using predefined sets.
|
|
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
|
+
from mcp_proxy_adapter.core.config.simple_config import (
|
|
15
|
+
SimpleConfig,
|
|
16
|
+
SimpleConfigModel,
|
|
17
|
+
ServerConfig,
|
|
18
|
+
ProxyClientConfig,
|
|
19
|
+
AuthConfig,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SetsCommand:
|
|
24
|
+
"""Command for generating configurations using predefined sets."""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Initialize the sets command."""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
def execute(self, args: Dict[str, Any]) -> int:
|
|
31
|
+
"""
|
|
32
|
+
Execute the sets command.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
args: Parsed command arguments
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Exit code (0 for success, 1 for error)
|
|
39
|
+
"""
|
|
40
|
+
set_name = args.get('set_name')
|
|
41
|
+
|
|
42
|
+
if not set_name:
|
|
43
|
+
print("❌ No set specified. Use: sets {http,https,mtls}")
|
|
44
|
+
return 1
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
# Generate configuration based on set
|
|
48
|
+
config_path = self._create_config_from_set(set_name, args)
|
|
49
|
+
|
|
50
|
+
print(f"✅ {set_name.upper()} configuration saved to: {config_path}")
|
|
51
|
+
return 0
|
|
52
|
+
|
|
53
|
+
except Exception as e:
|
|
54
|
+
print(f"❌ Error generating {set_name} configuration: {e}")
|
|
55
|
+
return 1
|
|
56
|
+
|
|
57
|
+
def _create_config_from_set(self, set_name: str, args: Dict[str, Any]) -> Path:
|
|
58
|
+
"""
|
|
59
|
+
Create configuration based on the specified set.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
set_name: Name of the configuration set
|
|
63
|
+
args: Command arguments
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Path to saved configuration file
|
|
67
|
+
"""
|
|
68
|
+
host = args.get('host', '127.0.0.1')
|
|
69
|
+
port = int(args.get('port', 8000))
|
|
70
|
+
protocol = set_name
|
|
71
|
+
|
|
72
|
+
# Build server config compatible with SimpleConfig
|
|
73
|
+
server = ServerConfig(host=host, port=port, protocol=protocol)
|
|
74
|
+
cert_dir = Path(args.get('cert_dir') or './certs')
|
|
75
|
+
key_dir = Path(args.get('key_dir') or './keys')
|
|
76
|
+
if protocol in ('https', 'mtls'):
|
|
77
|
+
# Prefer test-server.* filenames if present, otherwise fallback to server.*
|
|
78
|
+
cert_file = cert_dir / 'test-server.crt'
|
|
79
|
+
key_file = key_dir / 'test-server.key'
|
|
80
|
+
if not cert_file.exists():
|
|
81
|
+
cert_file = cert_dir / 'server.crt'
|
|
82
|
+
if not key_file.exists():
|
|
83
|
+
key_file = key_dir / 'server.key'
|
|
84
|
+
server.cert_file = str(cert_file)
|
|
85
|
+
server.key_file = str(key_file)
|
|
86
|
+
if protocol == 'mtls':
|
|
87
|
+
# CA file path is expected by validator; try ca/ca.crt relative to provided cert_dir
|
|
88
|
+
ca_candidate = cert_dir.parent / 'ca' / 'ca.crt'
|
|
89
|
+
if not ca_candidate.exists():
|
|
90
|
+
ca_candidate = cert_dir / 'ca.crt'
|
|
91
|
+
server.ca_cert_file = str(ca_candidate)
|
|
92
|
+
|
|
93
|
+
# Proxy client (disabled by default here)
|
|
94
|
+
proxy = ProxyClientConfig(enabled=False)
|
|
95
|
+
|
|
96
|
+
# Auth config based on modifiers
|
|
97
|
+
use_token = 'token' in (args.get('modifiers') or []) or bool(args.get('token'))
|
|
98
|
+
use_roles = 'roles' in (args.get('modifiers') or []) or bool(args.get('roles'))
|
|
99
|
+
# If roles are requested, token must be enabled to satisfy validator
|
|
100
|
+
if use_roles and not use_token:
|
|
101
|
+
use_token = True
|
|
102
|
+
tokens = {
|
|
103
|
+
'admin': ['read', 'write', 'delete', 'admin'],
|
|
104
|
+
} if use_token else {}
|
|
105
|
+
roles = {
|
|
106
|
+
'admin': ['read', 'write', 'delete', 'admin'],
|
|
107
|
+
'user': ['read', 'write'],
|
|
108
|
+
} if use_roles else {}
|
|
109
|
+
auth = AuthConfig(use_token=use_token, use_roles=use_roles, tokens=tokens, roles=roles)
|
|
110
|
+
|
|
111
|
+
# Save using SimpleConfig
|
|
112
|
+
model = SimpleConfigModel(server=server, proxy_client=proxy, auth=auth)
|
|
113
|
+
out_dir = Path(args.get('output_dir', './configs'))
|
|
114
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
115
|
+
name_parts = [set_name]
|
|
116
|
+
if use_token and set_name in ['http', 'https']:
|
|
117
|
+
name_parts.append('token')
|
|
118
|
+
if use_roles:
|
|
119
|
+
name_parts.append('roles')
|
|
120
|
+
filename = args.get('output') or "_".join(name_parts)
|
|
121
|
+
out_path = out_dir / f"{filename}.json"
|
|
122
|
+
|
|
123
|
+
cfg = SimpleConfig(str(out_path))
|
|
124
|
+
cfg.model = model
|
|
125
|
+
cfg.save()
|
|
126
|
+
return out_path
|
|
127
|
+
|
|
128
|
+
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TestConfig Command
|
|
3
|
+
|
|
4
|
+
This module implements the testconfig command for validating configuration files.
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from typing import Dict, Any
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from mcp_proxy_adapter.core.config_validator import ConfigValidator
|
|
15
|
+
VALIDATION_AVAILABLE = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
VALIDATION_AVAILABLE = False
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestConfigCommand:
|
|
21
|
+
"""Command for testing and validating configuration files."""
|
|
22
|
+
|
|
23
|
+
def __init__(self):
|
|
24
|
+
"""Initialize the testconfig command."""
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
def execute(self, args: Dict[str, Any]) -> int:
|
|
28
|
+
"""
|
|
29
|
+
Execute the testconfig command.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
args: Parsed command arguments
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Exit code (0 for success, 1 for error)
|
|
36
|
+
"""
|
|
37
|
+
if not VALIDATION_AVAILABLE:
|
|
38
|
+
print("❌ Configuration validation not available. Install the package to enable validation.")
|
|
39
|
+
return 1
|
|
40
|
+
|
|
41
|
+
config_file = args['config']
|
|
42
|
+
verbose = args.get('verbose', False)
|
|
43
|
+
fix_suggestions = args.get('fix_suggestions', False)
|
|
44
|
+
json_output = args.get('json', False)
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
# Load and validate configuration
|
|
48
|
+
validator = ConfigValidator(config_file)
|
|
49
|
+
validator.load_config()
|
|
50
|
+
results = validator.validate_config()
|
|
51
|
+
|
|
52
|
+
# Get validation summary
|
|
53
|
+
summary = validator.get_validation_summary()
|
|
54
|
+
|
|
55
|
+
if json_output:
|
|
56
|
+
# Output results in JSON format
|
|
57
|
+
self._output_json_results(summary, results, config_file)
|
|
58
|
+
else:
|
|
59
|
+
# Output human-readable results
|
|
60
|
+
self._output_human_results(summary, results, config_file, verbose, fix_suggestions)
|
|
61
|
+
|
|
62
|
+
# Return appropriate exit code
|
|
63
|
+
return 0 if summary['is_valid'] else 1
|
|
64
|
+
|
|
65
|
+
except Exception as e:
|
|
66
|
+
print(f"❌ Error testing configuration: {e}")
|
|
67
|
+
return 1
|
|
68
|
+
|
|
69
|
+
def _output_json_results(self, summary: Dict[str, Any], results: list, config_file: str) -> None:
|
|
70
|
+
"""Output validation results in JSON format."""
|
|
71
|
+
output = {
|
|
72
|
+
"config_file": config_file,
|
|
73
|
+
"summary": summary,
|
|
74
|
+
"issues": []
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for result in results:
|
|
78
|
+
issue = {
|
|
79
|
+
"level": result.level,
|
|
80
|
+
"message": result.message,
|
|
81
|
+
"section": result.section,
|
|
82
|
+
"key": result.key if hasattr(result, 'key') else None,
|
|
83
|
+
"suggestion": result.suggestion if hasattr(result, 'suggestion') else None
|
|
84
|
+
}
|
|
85
|
+
output["issues"].append(issue)
|
|
86
|
+
|
|
87
|
+
print(json.dumps(output, indent=2, ensure_ascii=False))
|
|
88
|
+
|
|
89
|
+
def _output_human_results(self, summary: Dict[str, Any], results: list, config_file: str,
|
|
90
|
+
verbose: bool, fix_suggestions: bool) -> None:
|
|
91
|
+
"""Output validation results in human-readable format."""
|
|
92
|
+
print("=" * 60)
|
|
93
|
+
print("CONFIGURATION VALIDATION REPORT")
|
|
94
|
+
print("=" * 60)
|
|
95
|
+
print(f"Configuration file: {config_file}")
|
|
96
|
+
print(f"Total issues: {summary['total_issues']}")
|
|
97
|
+
print(f"Errors: {summary['errors']}")
|
|
98
|
+
print(f"Warnings: {summary['warnings']}")
|
|
99
|
+
print(f"Info: {summary['info']}")
|
|
100
|
+
print(f"Configuration is valid: {'✅ YES' if summary['is_valid'] else '❌ NO'}")
|
|
101
|
+
print("=" * 60)
|
|
102
|
+
|
|
103
|
+
if results:
|
|
104
|
+
print("\n📋 DETAILED ISSUES:")
|
|
105
|
+
print("-" * 40)
|
|
106
|
+
|
|
107
|
+
for i, result in enumerate(results, 1):
|
|
108
|
+
level_symbol = {
|
|
109
|
+
"error": "❌",
|
|
110
|
+
"warning": "⚠️",
|
|
111
|
+
"info": "ℹ️"
|
|
112
|
+
}.get(result.level, "❓")
|
|
113
|
+
|
|
114
|
+
print(f"\n{i}. {level_symbol} [{result.level.upper()}]")
|
|
115
|
+
print(f" Message: {result.message}")
|
|
116
|
+
|
|
117
|
+
if hasattr(result, 'section') and result.section:
|
|
118
|
+
location = f"{result.section}"
|
|
119
|
+
if hasattr(result, 'key') and result.key:
|
|
120
|
+
location += f".{result.key}"
|
|
121
|
+
print(f" Location: {location}")
|
|
122
|
+
|
|
123
|
+
if hasattr(result, 'suggestion') and result.suggestion:
|
|
124
|
+
print(f" Suggestion: {result.suggestion}")
|
|
125
|
+
|
|
126
|
+
if verbose:
|
|
127
|
+
print(f" Full details: {result}")
|
|
128
|
+
else:
|
|
129
|
+
print("\n✅ No issues found in configuration!")
|
|
130
|
+
|
|
131
|
+
if fix_suggestions and results:
|
|
132
|
+
self._print_fix_suggestions(results)
|
|
133
|
+
|
|
134
|
+
def _print_fix_suggestions(self, results: list) -> None:
|
|
135
|
+
"""Print suggestions for fixing configuration issues."""
|
|
136
|
+
print("\n🔧 FIX SUGGESTIONS:")
|
|
137
|
+
print("-" * 40)
|
|
138
|
+
|
|
139
|
+
# Group suggestions by type
|
|
140
|
+
suggestions = {
|
|
141
|
+
"missing_files": [],
|
|
142
|
+
"invalid_values": [],
|
|
143
|
+
"missing_sections": [],
|
|
144
|
+
"dependency_issues": [],
|
|
145
|
+
"other": []
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
for result in results:
|
|
149
|
+
if result.level == "error":
|
|
150
|
+
message = result.message.lower()
|
|
151
|
+
if "does not exist" in message or "not found" in message:
|
|
152
|
+
suggestions["missing_files"].append(result)
|
|
153
|
+
elif "missing" in message and "section" in message:
|
|
154
|
+
suggestions["missing_sections"].append(result)
|
|
155
|
+
elif "invalid" in message or "wrong type" in message:
|
|
156
|
+
suggestions["invalid_values"].append(result)
|
|
157
|
+
elif "dependency" in message or "requires" in message:
|
|
158
|
+
suggestions["dependency_issues"].append(result)
|
|
159
|
+
else:
|
|
160
|
+
suggestions["other"].append(result)
|
|
161
|
+
|
|
162
|
+
# Print suggestions by category
|
|
163
|
+
for category, issues in suggestions.items():
|
|
164
|
+
if issues:
|
|
165
|
+
print(f"\n📁 {category.replace('_', ' ').title()}:")
|
|
166
|
+
for issue in issues:
|
|
167
|
+
print(f" • {issue.message}")
|
|
168
|
+
if hasattr(issue, 'suggestion') and issue.suggestion:
|
|
169
|
+
print(f" → {issue.suggestion}")
|
|
170
|
+
|
|
171
|
+
print("\n💡 GENERAL RECOMMENDATIONS:")
|
|
172
|
+
print(" • Use the configuration generator: mcp-proxy-adapter generate --help")
|
|
173
|
+
print(" • Check the documentation: docs/EN/ALL_CONFIG_SETTINGS.md")
|
|
174
|
+
print(" • Validate certificates and file paths")
|
|
175
|
+
print(" • Ensure all required sections are present")
|
|
176
|
+
|
|
177
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
HTTP Basic Configuration Example
|
|
4
|
+
|
|
5
|
+
This example demonstrates how to generate and use a basic HTTP configuration.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import subprocess
|
|
12
|
+
import sys
|
|
13
|
+
import json
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main():
|
|
18
|
+
"""Generate and test HTTP basic configuration."""
|
|
19
|
+
print("🔧 HTTP Basic Configuration Example")
|
|
20
|
+
print("=" * 50)
|
|
21
|
+
|
|
22
|
+
# Generate HTTP configuration
|
|
23
|
+
print("1. Generating HTTP configuration...")
|
|
24
|
+
result = subprocess.run([
|
|
25
|
+
sys.executable, "-m", "mcp_proxy_adapter.cli.main",
|
|
26
|
+
"sets", "http",
|
|
27
|
+
"--port", "8080",
|
|
28
|
+
"--output-dir", "./examples_configs"
|
|
29
|
+
], capture_output=True, text=True)
|
|
30
|
+
|
|
31
|
+
if result.returncode != 0:
|
|
32
|
+
print(f"❌ Error generating configuration: {result.stderr}")
|
|
33
|
+
return 1
|
|
34
|
+
|
|
35
|
+
print("✅ HTTP configuration generated")
|
|
36
|
+
|
|
37
|
+
# Find the generated config file
|
|
38
|
+
config_dir = Path("./examples_configs")
|
|
39
|
+
config_files = list(config_dir.glob("http*.json"))
|
|
40
|
+
|
|
41
|
+
if not config_files:
|
|
42
|
+
print("❌ No configuration files found")
|
|
43
|
+
return 1
|
|
44
|
+
|
|
45
|
+
config_file = config_files[0]
|
|
46
|
+
print(f"📁 Configuration file: {config_file}")
|
|
47
|
+
|
|
48
|
+
# Test the configuration
|
|
49
|
+
print("\n2. Testing configuration...")
|
|
50
|
+
result = subprocess.run([
|
|
51
|
+
sys.executable, "-m", "mcp_proxy_adapter.cli.main",
|
|
52
|
+
"testconfig",
|
|
53
|
+
"--config", str(config_file),
|
|
54
|
+
"--verbose"
|
|
55
|
+
], capture_output=True, text=True)
|
|
56
|
+
|
|
57
|
+
if result.returncode != 0:
|
|
58
|
+
print(f"❌ Configuration validation failed: {result.stderr}")
|
|
59
|
+
return 1
|
|
60
|
+
|
|
61
|
+
print("✅ Configuration validation passed")
|
|
62
|
+
|
|
63
|
+
# Show configuration content
|
|
64
|
+
print("\n3. Configuration content:")
|
|
65
|
+
with open(config_file, 'r') as f:
|
|
66
|
+
config = json.load(f)
|
|
67
|
+
|
|
68
|
+
print(f" Protocol: {config['server']['protocol']}")
|
|
69
|
+
print(f" Host: {config['server']['host']}")
|
|
70
|
+
print(f" Port: {config['server']['port']}")
|
|
71
|
+
print(f" Security: {'Enabled' if config.get('security', {}).get('enabled') else 'Disabled'}")
|
|
72
|
+
|
|
73
|
+
print("\n🎉 HTTP basic configuration example completed!")
|
|
74
|
+
print(f"📁 Configuration saved to: {config_file}")
|
|
75
|
+
print("\n💡 To start the server:")
|
|
76
|
+
print(f" mcp-proxy-adapter server --config {config_file}")
|
|
77
|
+
|
|
78
|
+
return 0
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if __name__ == "__main__":
|
|
82
|
+
sys.exit(main())
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
HTTPS Token Configuration Example
|
|
4
|
+
|
|
5
|
+
This example demonstrates how to generate and use an HTTPS configuration with token authentication.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import subprocess
|
|
12
|
+
import sys
|
|
13
|
+
import json
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main():
|
|
18
|
+
"""Generate and test HTTPS token configuration."""
|
|
19
|
+
print("🔧 HTTPS Token Configuration Example")
|
|
20
|
+
print("=" * 50)
|
|
21
|
+
|
|
22
|
+
# Generate HTTPS configuration with token authentication
|
|
23
|
+
print("1. Generating HTTPS configuration with token authentication...")
|
|
24
|
+
result = subprocess.run([
|
|
25
|
+
sys.executable, "-m", "mcp_proxy_adapter.cli.main",
|
|
26
|
+
"sets", "https",
|
|
27
|
+
"--token",
|
|
28
|
+
"--roles",
|
|
29
|
+
"--port", "8443",
|
|
30
|
+
"--output-dir", "./examples_configs"
|
|
31
|
+
], capture_output=True, text=True)
|
|
32
|
+
|
|
33
|
+
if result.returncode != 0:
|
|
34
|
+
print(f"❌ Error generating configuration: {result.stderr}")
|
|
35
|
+
return 1
|
|
36
|
+
|
|
37
|
+
print("✅ HTTPS configuration with token authentication generated")
|
|
38
|
+
|
|
39
|
+
# Find the generated config file
|
|
40
|
+
config_dir = Path("./examples_configs")
|
|
41
|
+
config_files = list(config_dir.glob("https_token_roles*.json"))
|
|
42
|
+
|
|
43
|
+
if not config_files:
|
|
44
|
+
print("❌ No configuration files found")
|
|
45
|
+
return 1
|
|
46
|
+
|
|
47
|
+
config_file = config_files[0]
|
|
48
|
+
print(f"📁 Configuration file: {config_file}")
|
|
49
|
+
|
|
50
|
+
# Test the configuration
|
|
51
|
+
print("\n2. Testing configuration...")
|
|
52
|
+
result = subprocess.run([
|
|
53
|
+
sys.executable, "-m", "mcp_proxy_adapter.cli.main",
|
|
54
|
+
"testconfig",
|
|
55
|
+
"--config", str(config_file),
|
|
56
|
+
"--verbose"
|
|
57
|
+
], capture_output=True, text=True)
|
|
58
|
+
|
|
59
|
+
if result.returncode != 0:
|
|
60
|
+
print(f"❌ Configuration validation failed: {result.stderr}")
|
|
61
|
+
return 1
|
|
62
|
+
|
|
63
|
+
print("✅ Configuration validation passed")
|
|
64
|
+
|
|
65
|
+
# Show configuration content
|
|
66
|
+
print("\n3. Configuration content:")
|
|
67
|
+
with open(config_file, 'r') as f:
|
|
68
|
+
config = json.load(f)
|
|
69
|
+
|
|
70
|
+
print(f" Protocol: {config['server']['protocol']}")
|
|
71
|
+
print(f" Host: {config['server']['host']}")
|
|
72
|
+
print(f" Port: {config['server']['port']}")
|
|
73
|
+
print(f" SSL: {'Enabled' if config.get('ssl', {}).get('enabled') else 'Disabled'}")
|
|
74
|
+
print(f" Security: {'Enabled' if config.get('security', {}).get('enabled') else 'Disabled'}")
|
|
75
|
+
print(f" Token Auth: {'Enabled' if config.get('security', {}).get('tokens') else 'Disabled'}")
|
|
76
|
+
print(f" Roles: {'Enabled' if config.get('roles', {}).get('enabled') else 'Disabled'}")
|
|
77
|
+
|
|
78
|
+
# Show available tokens
|
|
79
|
+
if config.get('security', {}).get('tokens'):
|
|
80
|
+
print("\n4. Available authentication tokens:")
|
|
81
|
+
for role, token in config['security']['tokens'].items():
|
|
82
|
+
print(f" {role}: {token}")
|
|
83
|
+
|
|
84
|
+
print("\n🎉 HTTPS token configuration example completed!")
|
|
85
|
+
print(f"📁 Configuration saved to: {config_file}")
|
|
86
|
+
print("\n💡 To start the server:")
|
|
87
|
+
print(f" mcp-proxy-adapter server --config {config_file}")
|
|
88
|
+
print("\n💡 To test with curl:")
|
|
89
|
+
print(f" curl -k https://localhost:8443/health")
|
|
90
|
+
print(f" curl -k -H 'X-API-Key: admin-secret-key' https://localhost:8443/api/jsonrpc -d '{{\"jsonrpc\":\"2.0\",\"method\":\"echo\",\"params\":{{\"message\":\"Hello\"}},\"id\":1}}'")
|
|
91
|
+
|
|
92
|
+
return 0
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if __name__ == "__main__":
|
|
96
|
+
sys.exit(main())
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
mTLS Roles Configuration Example
|
|
4
|
+
|
|
5
|
+
This example demonstrates how to generate and use an mTLS configuration with role-based access control.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import subprocess
|
|
12
|
+
import sys
|
|
13
|
+
import json
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main():
|
|
18
|
+
"""Generate and test mTLS roles configuration."""
|
|
19
|
+
print("🔧 mTLS Roles Configuration Example")
|
|
20
|
+
print("=" * 50)
|
|
21
|
+
|
|
22
|
+
# Generate mTLS configuration with roles
|
|
23
|
+
print("1. Generating mTLS configuration with roles...")
|
|
24
|
+
result = subprocess.run([
|
|
25
|
+
sys.executable, "-m", "mcp_proxy_adapter.cli.main",
|
|
26
|
+
"sets", "mtls",
|
|
27
|
+
"--roles",
|
|
28
|
+
"--port", "8443",
|
|
29
|
+
"--output-dir", "./examples_configs"
|
|
30
|
+
], capture_output=True, text=True)
|
|
31
|
+
|
|
32
|
+
if result.returncode != 0:
|
|
33
|
+
print(f"❌ Error generating configuration: {result.stderr}")
|
|
34
|
+
return 1
|
|
35
|
+
|
|
36
|
+
print("✅ mTLS configuration with roles generated")
|
|
37
|
+
|
|
38
|
+
# Find the generated config file
|
|
39
|
+
config_dir = Path("./examples_configs")
|
|
40
|
+
config_files = list(config_dir.glob("mtls_roles*.json"))
|
|
41
|
+
|
|
42
|
+
if not config_files:
|
|
43
|
+
print("❌ No configuration files found")
|
|
44
|
+
return 1
|
|
45
|
+
|
|
46
|
+
config_file = config_files[0]
|
|
47
|
+
print(f"📁 Configuration file: {config_file}")
|
|
48
|
+
|
|
49
|
+
# Test the configuration
|
|
50
|
+
print("\n2. Testing configuration...")
|
|
51
|
+
result = subprocess.run([
|
|
52
|
+
sys.executable, "-m", "mcp_proxy_adapter.cli.main",
|
|
53
|
+
"testconfig",
|
|
54
|
+
"--config", str(config_file),
|
|
55
|
+
"--verbose"
|
|
56
|
+
], capture_output=True, text=True)
|
|
57
|
+
|
|
58
|
+
if result.returncode != 0:
|
|
59
|
+
print(f"❌ Configuration validation failed: {result.stderr}")
|
|
60
|
+
return 1
|
|
61
|
+
|
|
62
|
+
print("✅ Configuration validation passed")
|
|
63
|
+
|
|
64
|
+
# Show configuration content
|
|
65
|
+
print("\n3. Configuration content:")
|
|
66
|
+
with open(config_file, 'r') as f:
|
|
67
|
+
config = json.load(f)
|
|
68
|
+
|
|
69
|
+
print(f" Protocol: {config['server']['protocol']}")
|
|
70
|
+
print(f" Host: {config['server']['host']}")
|
|
71
|
+
print(f" Port: {config['server']['port']}")
|
|
72
|
+
print(f" SSL: {'Enabled' if config.get('ssl', {}).get('enabled') else 'Disabled'}")
|
|
73
|
+
print(f" Client Verification: {'Enabled' if config.get('transport', {}).get('verify_client') else 'Disabled'}")
|
|
74
|
+
print(f" Roles: {'Enabled' if config.get('roles', {}).get('enabled') else 'Disabled'}")
|
|
75
|
+
|
|
76
|
+
# Show SSL configuration
|
|
77
|
+
if config.get('ssl'):
|
|
78
|
+
ssl_config = config['ssl']
|
|
79
|
+
print(f"\n4. SSL Configuration:")
|
|
80
|
+
print(f" Certificate: {ssl_config.get('cert_file', 'Not set')}")
|
|
81
|
+
print(f" Private Key: {ssl_config.get('key_file', 'Not set')}")
|
|
82
|
+
print(f" CA Certificate: {ssl_config.get('ca_cert', 'Not set')}")
|
|
83
|
+
|
|
84
|
+
# Show roles configuration
|
|
85
|
+
if config.get('roles', {}).get('enabled'):
|
|
86
|
+
print(f"\n5. Roles Configuration:")
|
|
87
|
+
print(f" Config File: {config['roles'].get('config_file', 'Not set')}")
|
|
88
|
+
print(f" Auto Load: {config['roles'].get('auto_load', False)}")
|
|
89
|
+
print(f" Validation: {'Enabled' if config['roles'].get('validation_enabled') else 'Disabled'}")
|
|
90
|
+
|
|
91
|
+
print("\n🎉 mTLS roles configuration example completed!")
|
|
92
|
+
print(f"📁 Configuration saved to: {config_file}")
|
|
93
|
+
print("\n💡 To start the server:")
|
|
94
|
+
print(f" mcp-proxy-adapter server --config {config_file}")
|
|
95
|
+
print("\n💡 To test with curl (requires client certificates):")
|
|
96
|
+
print(f" curl -k --cert client.crt --key client.key https://localhost:8443/health")
|
|
97
|
+
print(f" curl -k --cert client.crt --key client.key https://localhost:8443/api/jsonrpc -d '{{\"jsonrpc\":\"2.0\",\"method\":\"echo\",\"params\":{{\"message\":\"Hello mTLS\"}},\"id\":1}}'")
|
|
98
|
+
|
|
99
|
+
return 0
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
sys.exit(main())
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
MCP Proxy Adapter CLI Application
|
|
4
|
+
Comprehensive command-line interface with multi-level help and configuration management
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
# Add project root to path
|
|
14
|
+
project_root = Path(__file__).parent.parent.parent
|
|
15
|
+
sys.path.insert(0, str(project_root))
|
|
16
|
+
|
|
17
|
+
from mcp_proxy_adapter.cli.parser import create_main_parser # noqa: E402
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main():
|
|
21
|
+
"""Main CLI entry point"""
|
|
22
|
+
parser = create_main_parser()
|
|
23
|
+
args = parser.parse_args()
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
if args.command == 'generate':
|
|
27
|
+
from mcp_proxy_adapter.cli.commands.generate import GenerateCommand
|
|
28
|
+
return GenerateCommand().execute(vars(args))
|
|
29
|
+
elif args.command == 'testconfig':
|
|
30
|
+
from mcp_proxy_adapter.cli.commands.testconfig import TestConfigCommand
|
|
31
|
+
return TestConfigCommand().execute(vars(args))
|
|
32
|
+
elif args.command == 'sets':
|
|
33
|
+
from mcp_proxy_adapter.cli.commands.sets import SetsCommand
|
|
34
|
+
return SetsCommand().execute(vars(args))
|
|
35
|
+
elif args.command == 'server':
|
|
36
|
+
from mcp_proxy_adapter.cli.commands.server import ServerCommand
|
|
37
|
+
return ServerCommand().execute(vars(args))
|
|
38
|
+
elif args.command == 'config':
|
|
39
|
+
if args.config_command == 'generate':
|
|
40
|
+
from mcp_proxy_adapter.cli.commands.config_generate import config_generate_command
|
|
41
|
+
return config_generate_command(args)
|
|
42
|
+
if args.config_command == 'validate':
|
|
43
|
+
from mcp_proxy_adapter.cli.commands.config_validate import config_validate_command
|
|
44
|
+
return config_validate_command(args)
|
|
45
|
+
print('Available: config generate|validate')
|
|
46
|
+
return 1
|
|
47
|
+
elif args.command == 'client':
|
|
48
|
+
from mcp_proxy_adapter.cli.commands.client import client_command
|
|
49
|
+
return client_command(args)
|
|
50
|
+
else:
|
|
51
|
+
parser.print_help()
|
|
52
|
+
return 1
|
|
53
|
+
|
|
54
|
+
except KeyboardInterrupt:
|
|
55
|
+
print("\n❌ Operation cancelled by user")
|
|
56
|
+
return 1
|
|
57
|
+
except Exception as e:
|
|
58
|
+
print(f"❌ Error: {e}")
|
|
59
|
+
return 1
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
sys.exit(main())
|