mcp-proxy-adapter 6.9.27__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 -912
- 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.27.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.27.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/entry_points.txt +1 -1
- mcp_proxy_adapter-6.9.27.dist-info/RECORD +0 -149
- {mcp_proxy_adapter-6.9.27.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.9.27.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Test environment setup package for MCP Proxy Adapter.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .config_validator import ConfigurationValidator
|
|
9
|
+
from .test_files_generator import create_test_files
|
|
10
|
+
from .config_generator import create_configuration_documentation, generate_enhanced_configurations
|
|
11
|
+
from .certificate_manager import generate_certificates_with_framework
|
|
12
|
+
from .test_runner import test_proxy_registration, run_full_test_suite
|
|
13
|
+
from .environment_setup import setup_test_environment
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ConfigurationValidator",
|
|
17
|
+
"create_test_files",
|
|
18
|
+
"create_configuration_documentation",
|
|
19
|
+
"generate_enhanced_configurations",
|
|
20
|
+
"generate_certificates_with_framework",
|
|
21
|
+
"test_proxy_registration",
|
|
22
|
+
"run_full_test_suite",
|
|
23
|
+
"setup_test_environment",
|
|
24
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Certificate manager for MCP Proxy Adapter test environment setup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import subprocess
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import bool
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def generate_certificates_with_framework(output_dir: Path) -> bool:
|
|
15
|
+
"""
|
|
16
|
+
Generate certificates using mcp_security_framework if available.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
output_dir: Directory to generate certificates in
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
True if certificates were generated successfully, False otherwise
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
from mcp_security_framework.core.cert_manager import CertificateManager
|
|
26
|
+
CertificateConfig,
|
|
27
|
+
CAConfig,
|
|
28
|
+
ServerCertConfig,
|
|
29
|
+
ClientCertConfig,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
print("🔐 Generating certificates using mcp_security_framework...")
|
|
33
|
+
|
|
34
|
+
# Create certificate directories
|
|
35
|
+
certs_dir = output_dir / "certs"
|
|
36
|
+
keys_dir = output_dir / "keys"
|
|
37
|
+
certs_dir.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
keys_dir.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
|
|
40
|
+
# Initialize certificate manager
|
|
41
|
+
cert_manager = CertificateManager()
|
|
42
|
+
|
|
43
|
+
# Generate CA certificate
|
|
44
|
+
ca_config = CAConfig(
|
|
45
|
+
common_name="MCP Test CA",
|
|
46
|
+
country="US",
|
|
47
|
+
state="Test State",
|
|
48
|
+
city="Test City",
|
|
49
|
+
organization="MCP Test Org",
|
|
50
|
+
organizational_unit="Test Unit",
|
|
51
|
+
validity_days=365
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
ca_cert_path = certs_dir / "ca_cert.pem"
|
|
55
|
+
ca_key_path = keys_dir / "ca_key.pem"
|
|
56
|
+
|
|
57
|
+
print("📜 Generating CA certificate...")
|
|
58
|
+
cert_manager.generate_ca_certificate(
|
|
59
|
+
ca_config,
|
|
60
|
+
str(ca_cert_path),
|
|
61
|
+
str(ca_key_path)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Generate server certificate
|
|
65
|
+
server_config = ServerCertConfig(
|
|
66
|
+
common_name="localhost",
|
|
67
|
+
san_dns=["localhost", "127.0.0.1"],
|
|
68
|
+
san_ip=["127.0.0.1", "::1"],
|
|
69
|
+
validity_days=365
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
server_cert_path = certs_dir / "localhost_server.crt"
|
|
73
|
+
server_key_path = keys_dir / "server_key.pem"
|
|
74
|
+
|
|
75
|
+
print("🖥️ Generating server certificate...")
|
|
76
|
+
cert_manager.generate_server_certificate(
|
|
77
|
+
server_config,
|
|
78
|
+
str(server_cert_path),
|
|
79
|
+
str(server_key_path),
|
|
80
|
+
str(ca_cert_path),
|
|
81
|
+
str(ca_key_path)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Generate client certificate
|
|
85
|
+
client_config = ClientCertConfig(
|
|
86
|
+
common_name="test-client",
|
|
87
|
+
validity_days=365
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
client_cert_path = certs_dir / "client_cert.pem"
|
|
91
|
+
client_key_path = keys_dir / "client_key.pem"
|
|
92
|
+
|
|
93
|
+
print("👤 Generating client certificate...")
|
|
94
|
+
cert_manager.generate_client_certificate(
|
|
95
|
+
client_config,
|
|
96
|
+
str(client_cert_path),
|
|
97
|
+
str(client_key_path),
|
|
98
|
+
str(ca_cert_path),
|
|
99
|
+
str(ca_key_path)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
print("✅ Certificates generated successfully!")
|
|
103
|
+
print(f" CA Certificate: {ca_cert_path}")
|
|
104
|
+
print(f" Server Certificate: {server_cert_path}")
|
|
105
|
+
print(f" Client Certificate: {client_cert_path}")
|
|
106
|
+
|
|
107
|
+
return True
|
|
108
|
+
|
|
109
|
+
except ImportError:
|
|
110
|
+
print("⚠️ mcp_security_framework not available, using OpenSSL fallback...")
|
|
111
|
+
return _generate_certificates_with_openssl(output_dir)
|
|
112
|
+
except Exception as e:
|
|
113
|
+
print(f"❌ Error generating certificates with framework: {e}")
|
|
114
|
+
print("🔄 Falling back to OpenSSL...")
|
|
115
|
+
return _generate_certificates_with_openssl(output_dir)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _generate_certificates_with_openssl(output_dir: Path) -> bool:
|
|
119
|
+
"""
|
|
120
|
+
Generate certificates using OpenSSL as fallback.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
output_dir: Directory to generate certificates in
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
True if certificates were generated successfully, False otherwise
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
print("🔐 Generating certificates using OpenSSL...")
|
|
130
|
+
|
|
131
|
+
# Create certificate directories
|
|
132
|
+
certs_dir = output_dir / "certs"
|
|
133
|
+
keys_dir = output_dir / "keys"
|
|
134
|
+
certs_dir.mkdir(parents=True, exist_ok=True)
|
|
135
|
+
keys_dir.mkdir(parents=True, exist_ok=True)
|
|
136
|
+
|
|
137
|
+
# Generate CA private key
|
|
138
|
+
ca_key_path = keys_dir / "ca_key.pem"
|
|
139
|
+
subprocess.run([
|
|
140
|
+
"openssl", "genrsa", "-out", str(ca_key_path), "2048"
|
|
141
|
+
], check=True)
|
|
142
|
+
|
|
143
|
+
# Generate CA certificate
|
|
144
|
+
ca_cert_path = certs_dir / "ca_cert.pem"
|
|
145
|
+
subprocess.run([
|
|
146
|
+
"openssl", "req", "-new", "-x509", "-key", str(ca_key_path),
|
|
147
|
+
"-out", str(ca_cert_path), "-days", "365",
|
|
148
|
+
"-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=MCP Test CA"
|
|
149
|
+
], check=True)
|
|
150
|
+
|
|
151
|
+
# Generate server private key
|
|
152
|
+
server_key_path = keys_dir / "server_key.pem"
|
|
153
|
+
subprocess.run([
|
|
154
|
+
"openssl", "genrsa", "-out", str(server_key_path), "2048"
|
|
155
|
+
], check=True)
|
|
156
|
+
|
|
157
|
+
# Generate server certificate request
|
|
158
|
+
server_csr_path = certs_dir / "server.csr"
|
|
159
|
+
subprocess.run([
|
|
160
|
+
"openssl", "req", "-new", "-key", str(server_key_path),
|
|
161
|
+
"-out", str(server_csr_path),
|
|
162
|
+
"-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=localhost"
|
|
163
|
+
], check=True)
|
|
164
|
+
|
|
165
|
+
# Generate server certificate
|
|
166
|
+
server_cert_path = certs_dir / "localhost_server.crt"
|
|
167
|
+
subprocess.run([
|
|
168
|
+
"openssl", "x509", "-req", "-in", str(server_csr_path),
|
|
169
|
+
"-CA", str(ca_cert_path), "-CAkey", str(ca_key_path),
|
|
170
|
+
"-out", str(server_cert_path), "-days", "365",
|
|
171
|
+
"-CAcreateserial"
|
|
172
|
+
], check=True)
|
|
173
|
+
|
|
174
|
+
# Generate client private key
|
|
175
|
+
client_key_path = keys_dir / "client_key.pem"
|
|
176
|
+
subprocess.run([
|
|
177
|
+
"openssl", "genrsa", "-out", str(client_key_path), "2048"
|
|
178
|
+
], check=True)
|
|
179
|
+
|
|
180
|
+
# Generate client certificate request
|
|
181
|
+
client_csr_path = certs_dir / "client.csr"
|
|
182
|
+
subprocess.run([
|
|
183
|
+
"openssl", "req", "-new", "-key", str(client_key_path),
|
|
184
|
+
"-out", str(client_csr_path),
|
|
185
|
+
"-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=test-client"
|
|
186
|
+
], check=True)
|
|
187
|
+
|
|
188
|
+
# Generate client certificate
|
|
189
|
+
client_cert_path = certs_dir / "client_cert.pem"
|
|
190
|
+
subprocess.run([
|
|
191
|
+
"openssl", "x509", "-req", "-in", str(client_csr_path),
|
|
192
|
+
"-CA", str(ca_cert_path), "-CAkey", str(ca_key_path),
|
|
193
|
+
"-out", str(client_cert_path), "-days", "365"
|
|
194
|
+
], check=True)
|
|
195
|
+
|
|
196
|
+
# Clean up CSR files
|
|
197
|
+
server_csr_path.unlink(missing_ok=True)
|
|
198
|
+
client_csr_path.unlink(missing_ok=True)
|
|
199
|
+
|
|
200
|
+
print("✅ Certificates generated successfully with OpenSSL!")
|
|
201
|
+
print(f" CA Certificate: {ca_cert_path}")
|
|
202
|
+
print(f" Server Certificate: {server_cert_path}")
|
|
203
|
+
print(f" Client Certificate: {client_cert_path}")
|
|
204
|
+
|
|
205
|
+
return True
|
|
206
|
+
|
|
207
|
+
except subprocess.CalledProcessError as e:
|
|
208
|
+
print(f"❌ OpenSSL command failed: {e}")
|
|
209
|
+
return False
|
|
210
|
+
except FileNotFoundError:
|
|
211
|
+
print("❌ OpenSSL not found. Please install OpenSSL or mcp_security_framework")
|
|
212
|
+
return False
|
|
213
|
+
except Exception as e:
|
|
214
|
+
print(f"❌ Error generating certificates with OpenSSL: {e}")
|
|
215
|
+
return False
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Configuration validator for MCP Proxy Adapter test environment setup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, List, Any, Tuple
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ConfigurationValidator:
|
|
12
|
+
"""
|
|
13
|
+
Validates MCP Proxy Adapter configurations for mutually exclusive settings
|
|
14
|
+
and protocol compatibility.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.errors: List[str] = []
|
|
19
|
+
self.warnings: List[str] = []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _validate_protocol_settings(
|
|
23
|
+
self, config: Dict[str, Any], config_name: str
|
|
24
|
+
) -> None:
|
|
25
|
+
"""Validate protocol configuration settings."""
|
|
26
|
+
protocols = config.get("protocols", {})
|
|
27
|
+
|
|
28
|
+
if not protocols.get("enabled", False):
|
|
29
|
+
self.warnings.append(
|
|
30
|
+
f"⚠️ {config_name}: Protocol middleware is disabled - all protocols will be allowed"
|
|
31
|
+
)
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
allowed_protocols = protocols.get("allowed_protocols", [])
|
|
35
|
+
if not allowed_protocols:
|
|
36
|
+
self.errors.append(
|
|
37
|
+
f"❌ {config_name}: No allowed protocols specified when protocol middleware is enabled"
|
|
38
|
+
)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
# Check for invalid protocol combinations
|
|
42
|
+
if "http" in allowed_protocols and "https" in allowed_protocols:
|
|
43
|
+
self.warnings.append(
|
|
44
|
+
f"⚠️ {config_name}: Both HTTP and HTTPS protocols are allowed - consider security implications"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if "mtls" in allowed_protocols and "http" in allowed_protocols:
|
|
48
|
+
self.errors.append(
|
|
49
|
+
f"❌ {config_name}: mTLS and HTTP protocols are mutually exclusive - mTLS requires HTTPS"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def _validate_ssl_settings(self, config: Dict[str, Any], config_name: str) -> None:
|
|
53
|
+
"""Validate SSL/TLS configuration settings."""
|
|
54
|
+
security = config.get("security", {})
|
|
55
|
+
ssl = security.get("ssl", {})
|
|
56
|
+
|
|
57
|
+
if not ssl.get("enabled", False):
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
# Check certificate file requirements
|
|
61
|
+
cert_file = ssl.get("server_cert_file")
|
|
62
|
+
key_file = ssl.get("server_key_file")
|
|
63
|
+
|
|
64
|
+
if not cert_file or not key_file:
|
|
65
|
+
self.errors.append(
|
|
66
|
+
f"❌ {config_name}: SSL enabled but server certificate or key file not specified"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Check CA certificate requirements
|
|
70
|
+
ca_cert_file = ssl.get("ca_cert_file")
|
|
71
|
+
verify_server = ssl.get("verify_server", True)
|
|
72
|
+
|
|
73
|
+
if verify_server and not ca_cert_file:
|
|
74
|
+
self.warnings.append(
|
|
75
|
+
f"⚠️ {config_name}: Server verification enabled but no CA certificate specified"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def _validate_mtls_settings(self, config: Dict[str, Any], config_name: str) -> None:
|
|
79
|
+
"""Validate mTLS configuration settings."""
|
|
80
|
+
security = config.get("security", {})
|
|
81
|
+
ssl = security.get("ssl", {})
|
|
82
|
+
|
|
83
|
+
if not ssl.get("enabled", False):
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
# Check if mTLS is configured
|
|
87
|
+
client_cert_file = ssl.get("client_cert_file")
|
|
88
|
+
client_key_file = ssl.get("client_key_file")
|
|
89
|
+
verify_client = ssl.get("verify_client", False)
|
|
90
|
+
|
|
91
|
+
if verify_client and (not client_cert_file or not client_key_file):
|
|
92
|
+
self.errors.append(
|
|
93
|
+
f"❌ {config_name}: Client verification enabled but client certificate or key file not specified"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Check protocol compatibility
|
|
97
|
+
protocols = config.get("protocols", {})
|
|
98
|
+
if protocols.get("enabled", False):
|
|
99
|
+
allowed_protocols = protocols.get("allowed_protocols", [])
|
|
100
|
+
if verify_client and "mtls" not in allowed_protocols:
|
|
101
|
+
self.warnings.append(
|
|
102
|
+
f"⚠️ {config_name}: Client verification enabled but 'mtls' not in allowed protocols"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def _validate_auth_settings(self, config: Dict[str, Any], config_name: str) -> None:
|
|
106
|
+
"""Validate authentication configuration settings."""
|
|
107
|
+
security = config.get("security", {})
|
|
108
|
+
auth = security.get("auth", {})
|
|
109
|
+
|
|
110
|
+
if not auth.get("enabled", False):
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
# Check token requirements
|
|
114
|
+
token_required = auth.get("token_required", False)
|
|
115
|
+
if token_required and not auth.get("token_secret"):
|
|
116
|
+
self.errors.append(
|
|
117
|
+
f"❌ {config_name}: Token authentication enabled but no token secret specified"
|
|
118
|
+
)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Environment setup for MCP Proxy Adapter test environment.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import bool
|
|
11
|
+
|
|
12
|
+
from .config_generator import create_configuration_documentation, generate_enhanced_configurations
|
|
13
|
+
from .test_files_generator import create_test_files
|
|
14
|
+
from .certificate_manager import generate_certificates_with_framework
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _create_directory_structure(output_dir: Path) -> None:
|
|
20
|
+
"""Create the required directory structure."""
|
|
21
|
+
directories = [
|
|
22
|
+
"configs",
|
|
23
|
+
"certs",
|
|
24
|
+
"keys",
|
|
25
|
+
"docs",
|
|
26
|
+
"examples",
|
|
27
|
+
"logs"
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
for directory in directories:
|
|
31
|
+
dir_path = output_dir / directory
|
|
32
|
+
dir_path.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
print(f" Created: {dir_path}")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _copy_example_files(output_dir: Path) -> None:
|
|
37
|
+
"""Copy example files from the package."""
|
|
38
|
+
try:
|
|
39
|
+
# Get package paths
|
|
40
|
+
package_path = Path(__file__).parent.parent.parent.parent
|
|
41
|
+
examples_path = package_path / "examples"
|
|
42
|
+
|
|
43
|
+
# Copy example files
|
|
44
|
+
examples_dest = output_dir / "examples"
|
|
45
|
+
if examples_path.exists():
|
|
46
|
+
shutil.copytree(examples_path, examples_dest, dirs_exist_ok=True)
|
|
47
|
+
print(f" Copied examples to: {examples_dest}")
|
|
48
|
+
else:
|
|
49
|
+
print(" ⚠️ Examples directory not found, skipping...")
|
|
50
|
+
|
|
51
|
+
except Exception as e:
|
|
52
|
+
print(f" ⚠️ Error copying example files: {e}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _create_setup_completion_marker(output_dir: Path) -> None:
|
|
56
|
+
"""Create a marker file indicating setup completion."""
|
|
57
|
+
marker_file = output_dir / ".setup_complete"
|
|
58
|
+
with open(marker_file, "w", encoding="utf-8") as f:
|
|
59
|
+
f.write("MCP Proxy Adapter test environment setup completed successfully.\n")
|
|
60
|
+
f.write("Generated by setup_test_environment.py\n")
|
|
61
|
+
|
|
62
|
+
print(f" Created setup marker: {marker_file}")
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: Vasiliy Zdanovskiy
|
|
3
|
+
email: vasilyvz@gmail.com
|
|
4
|
+
|
|
5
|
+
Test runner for MCP Proxy Adapter test environment setup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import bool
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _test_basic_connectivity() -> bool:
|
|
18
|
+
"""Test basic network connectivity."""
|
|
19
|
+
try:
|
|
20
|
+
import socket
|
|
21
|
+
|
|
22
|
+
# Test if we can create a socket
|
|
23
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
24
|
+
s.settimeout(1)
|
|
25
|
+
# This is a basic connectivity test
|
|
26
|
+
print("✅ Basic connectivity test passed")
|
|
27
|
+
return True
|
|
28
|
+
|
|
29
|
+
except Exception as e:
|
|
30
|
+
print(f"❌ Basic connectivity test failed: {e}")
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _test_configuration_validation() -> bool:
|
|
35
|
+
"""Test configuration validation."""
|
|
36
|
+
try:
|
|
37
|
+
from .config_validator import ConfigurationValidator
|
|
38
|
+
|
|
39
|
+
validator = ConfigurationValidator()
|
|
40
|
+
|
|
41
|
+
# Test valid configuration
|
|
42
|
+
valid_config = {
|
|
43
|
+
"protocols": {"enabled": True, "allowed_protocols": ["https"]},
|
|
44
|
+
"security": {"ssl": {"enabled": True}}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
is_valid, errors, warnings = validator.validate_config(valid_config, "test")
|
|
48
|
+
|
|
49
|
+
if is_valid:
|
|
50
|
+
print("✅ Configuration validation test passed")
|
|
51
|
+
return True
|
|
52
|
+
else:
|
|
53
|
+
print(f"❌ Configuration validation test failed: {errors}")
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
except Exception as e:
|
|
57
|
+
print(f"❌ Configuration validation test failed: {e}")
|
|
58
|
+
return False
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _test_certificates() -> bool:
|
|
62
|
+
"""Test certificate files."""
|
|
63
|
+
try:
|
|
64
|
+
certs_dir = Path("certs")
|
|
65
|
+
keys_dir = Path("keys")
|
|
66
|
+
|
|
67
|
+
if not certs_dir.exists() or not keys_dir.exists():
|
|
68
|
+
print("⚠️ Certificate directories not found, skipping certificate test")
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
# Check for required certificate files
|
|
72
|
+
required_files = [
|
|
73
|
+
certs_dir / "ca_cert.pem",
|
|
74
|
+
certs_dir / "localhost_server.crt",
|
|
75
|
+
keys_dir / "server_key.pem"
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
missing_files = [f for f in required_files if not f.exists()]
|
|
79
|
+
|
|
80
|
+
if missing_files:
|
|
81
|
+
print(f"⚠️ Missing certificate files: {missing_files}")
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
print("✅ Certificate test passed")
|
|
85
|
+
return True
|
|
86
|
+
|
|
87
|
+
except Exception as e:
|
|
88
|
+
print(f"❌ Certificate test failed: {e}")
|
|
89
|
+
return False
|