mcp-proxy-adapter 6.4.44__tar.gz → 6.4.45__tar.gz
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.
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/PKG-INFO +81 -1
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/README.md +80 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/proxy_registration.py +100 -68
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/bugfix_certificate_config.py +284 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/config_builder.py +574 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/config_cli.py +283 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/create_test_configs.py +220 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/generate_certificates_bugfix.py +374 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/generate_certificates_cli.py +406 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/generate_certificates_fixed.py +313 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/generate_certificates_framework.py +366 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/generate_certificates_openssl.py +391 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/required_certificates.py +210 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/run_full_test_suite.py +117 -13
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/run_security_tests_fixed.py +42 -26
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/security_test_client.py +332 -85
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/test_config_builder.py +450 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter/examples/update_config_certificates.py +136 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter.egg-info/PKG-INFO +81 -1
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter.egg-info/SOURCES.txt +24 -0
- mcp_proxy_adapter-6.4.45/mcp_proxy_adapter.egg-info/entry_points.txt +12 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/pyproject.toml +11 -1
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/setup.py +7 -0
- mcp_proxy_adapter-6.4.44/mcp_proxy_adapter/examples/create_test_configs.py +0 -317
- mcp_proxy_adapter-6.4.44/mcp_proxy_adapter.egg-info/entry_points.txt +0 -2
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/__main__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/app.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/handlers.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/base.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/error_handling.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/factory.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/logging.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/performance.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/protocol_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/unified_security.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/schemas.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/tool_integration.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/api/tools.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/auth_validation_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/base.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/builtin_commands.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/catalog_manager.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/cert_monitor_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/certificate_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/command_registry.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/config_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/dependency_container.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/dependency_manager.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/echo_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/health_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/help_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/hooks.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/key_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/load_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/plugins_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/protocol_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/proxy_registration_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/reload_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/result.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/role_test_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/roles_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/security_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/settings_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/ssl_setup_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/token_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/transport_management_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/commands/unload_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/config.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/app_factory.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/app_runner.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/auth_validator.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/certificate_utils.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/client.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/client_manager.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/client_security.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/config_converter.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/config_validator.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/crl_utils.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/errors.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/logging.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/mtls_asgi.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/mtls_asgi_app.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/mtls_server.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/protocol_manager.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/proxy_client.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/role_utils.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/security_adapter.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/security_factory.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/security_integration.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/server_adapter.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/server_engine.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/settings.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/ssl_utils.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/transport_manager.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/unified_config_adapter.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/utils.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/custom_openapi.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/basic_framework/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/basic_framework/main.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/debug_request_state.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/debug_role_chain.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/demo_client.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/main.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/generate_all_certificates.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/proxy_registration_example.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/run_example.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/run_proxy_server.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/setup_test_environment.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/simple_protocol_test.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/test_config.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/test_examples.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/test_protocol_examples.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/examples/universal_client.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/main.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/openapi.py +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter.egg-info/dependency_links.txt +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter.egg-info/not-zip-safe +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter.egg-info/requires.txt +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter.egg-info/top_level.txt +0 -0
- {mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-proxy-adapter
|
3
|
-
Version: 6.4.
|
3
|
+
Version: 6.4.45
|
4
4
|
Summary: Powerful JSON-RPC microservices framework with built-in security, authentication, and proxy registration
|
5
5
|
Home-page: https://github.com/maverikod/mcp-proxy-adapter
|
6
6
|
Author: Vasiliy Zdanovskiy
|
@@ -138,6 +138,86 @@ The `mcp_proxy_adapter/examples/` directory contains comprehensive examples for
|
|
138
138
|
- **Security Testing**: Comprehensive security test suite
|
139
139
|
- **Certificate Generation**: SSL/TLS certificate management
|
140
140
|
|
141
|
+
### Test Environment Setup
|
142
|
+
|
143
|
+
The framework includes a comprehensive test environment setup that automatically creates configurations, generates certificates, and runs tests:
|
144
|
+
|
145
|
+
```bash
|
146
|
+
# Create a complete test environment with all configurations and certificates
|
147
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment
|
148
|
+
|
149
|
+
# Create test environment in a specific directory
|
150
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment /path/to/test/dir
|
151
|
+
|
152
|
+
# Skip certificate generation (use existing certificates)
|
153
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment --skip-certs
|
154
|
+
|
155
|
+
# Skip running tests (setup only)
|
156
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment --skip-tests
|
157
|
+
```
|
158
|
+
|
159
|
+
### Configuration Generation
|
160
|
+
|
161
|
+
Generate test configurations from a comprehensive template:
|
162
|
+
|
163
|
+
```bash
|
164
|
+
# Generate all test configurations
|
165
|
+
python -m mcp_proxy_adapter.examples.create_test_configs
|
166
|
+
|
167
|
+
# Generate from specific comprehensive config
|
168
|
+
python -m mcp_proxy_adapter.examples.create_test_configs --comprehensive-config config.json
|
169
|
+
|
170
|
+
# Generate specific configuration types
|
171
|
+
python -m mcp_proxy_adapter.examples.create_test_configs --types http,https,mtls
|
172
|
+
```
|
173
|
+
|
174
|
+
### Certificate Generation
|
175
|
+
|
176
|
+
Generate SSL/TLS certificates for testing:
|
177
|
+
|
178
|
+
```bash
|
179
|
+
# Generate all certificates using mcp_security_framework
|
180
|
+
python -m mcp_proxy_adapter.examples.generate_all_certificates
|
181
|
+
|
182
|
+
# Generate certificates with custom configuration
|
183
|
+
python -m mcp_proxy_adapter.examples.generate_certificates_framework --config cert_config.json
|
184
|
+
```
|
185
|
+
|
186
|
+
### Security Testing
|
187
|
+
|
188
|
+
Run comprehensive security tests:
|
189
|
+
|
190
|
+
```bash
|
191
|
+
# Run all security tests
|
192
|
+
python -m mcp_proxy_adapter.examples.run_security_tests_fixed
|
193
|
+
|
194
|
+
# Run full test suite (includes setup, config generation, certificate generation, and testing)
|
195
|
+
python -m mcp_proxy_adapter.examples.run_full_test_suite
|
196
|
+
```
|
197
|
+
|
198
|
+
### Complete Workflow Example
|
199
|
+
|
200
|
+
```bash
|
201
|
+
# 1. Install the package
|
202
|
+
pip install mcp-proxy-adapter
|
203
|
+
|
204
|
+
# 2. Create test environment (automatically runs tests)
|
205
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment
|
206
|
+
|
207
|
+
# 3. Or run individual steps:
|
208
|
+
# Generate certificates
|
209
|
+
python -m mcp_proxy_adapter.examples.generate_all_certificates
|
210
|
+
|
211
|
+
# Generate configurations
|
212
|
+
python -m mcp_proxy_adapter.examples.create_test_configs
|
213
|
+
|
214
|
+
# Run security tests
|
215
|
+
python -m mcp_proxy_adapter.examples.run_security_tests_fixed
|
216
|
+
|
217
|
+
# 4. Start server with generated configuration
|
218
|
+
python -m mcp_proxy_adapter --config configs/http_simple.json
|
219
|
+
```
|
220
|
+
|
141
221
|
## Development
|
142
222
|
|
143
223
|
The project follows a modular architecture:
|
@@ -79,6 +79,86 @@ The `mcp_proxy_adapter/examples/` directory contains comprehensive examples for
|
|
79
79
|
- **Security Testing**: Comprehensive security test suite
|
80
80
|
- **Certificate Generation**: SSL/TLS certificate management
|
81
81
|
|
82
|
+
### Test Environment Setup
|
83
|
+
|
84
|
+
The framework includes a comprehensive test environment setup that automatically creates configurations, generates certificates, and runs tests:
|
85
|
+
|
86
|
+
```bash
|
87
|
+
# Create a complete test environment with all configurations and certificates
|
88
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment
|
89
|
+
|
90
|
+
# Create test environment in a specific directory
|
91
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment /path/to/test/dir
|
92
|
+
|
93
|
+
# Skip certificate generation (use existing certificates)
|
94
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment --skip-certs
|
95
|
+
|
96
|
+
# Skip running tests (setup only)
|
97
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment --skip-tests
|
98
|
+
```
|
99
|
+
|
100
|
+
### Configuration Generation
|
101
|
+
|
102
|
+
Generate test configurations from a comprehensive template:
|
103
|
+
|
104
|
+
```bash
|
105
|
+
# Generate all test configurations
|
106
|
+
python -m mcp_proxy_adapter.examples.create_test_configs
|
107
|
+
|
108
|
+
# Generate from specific comprehensive config
|
109
|
+
python -m mcp_proxy_adapter.examples.create_test_configs --comprehensive-config config.json
|
110
|
+
|
111
|
+
# Generate specific configuration types
|
112
|
+
python -m mcp_proxy_adapter.examples.create_test_configs --types http,https,mtls
|
113
|
+
```
|
114
|
+
|
115
|
+
### Certificate Generation
|
116
|
+
|
117
|
+
Generate SSL/TLS certificates for testing:
|
118
|
+
|
119
|
+
```bash
|
120
|
+
# Generate all certificates using mcp_security_framework
|
121
|
+
python -m mcp_proxy_adapter.examples.generate_all_certificates
|
122
|
+
|
123
|
+
# Generate certificates with custom configuration
|
124
|
+
python -m mcp_proxy_adapter.examples.generate_certificates_framework --config cert_config.json
|
125
|
+
```
|
126
|
+
|
127
|
+
### Security Testing
|
128
|
+
|
129
|
+
Run comprehensive security tests:
|
130
|
+
|
131
|
+
```bash
|
132
|
+
# Run all security tests
|
133
|
+
python -m mcp_proxy_adapter.examples.run_security_tests_fixed
|
134
|
+
|
135
|
+
# Run full test suite (includes setup, config generation, certificate generation, and testing)
|
136
|
+
python -m mcp_proxy_adapter.examples.run_full_test_suite
|
137
|
+
```
|
138
|
+
|
139
|
+
### Complete Workflow Example
|
140
|
+
|
141
|
+
```bash
|
142
|
+
# 1. Install the package
|
143
|
+
pip install mcp-proxy-adapter
|
144
|
+
|
145
|
+
# 2. Create test environment (automatically runs tests)
|
146
|
+
python -m mcp_proxy_adapter.examples.setup_test_environment
|
147
|
+
|
148
|
+
# 3. Or run individual steps:
|
149
|
+
# Generate certificates
|
150
|
+
python -m mcp_proxy_adapter.examples.generate_all_certificates
|
151
|
+
|
152
|
+
# Generate configurations
|
153
|
+
python -m mcp_proxy_adapter.examples.create_test_configs
|
154
|
+
|
155
|
+
# Run security tests
|
156
|
+
python -m mcp_proxy_adapter.examples.run_security_tests_fixed
|
157
|
+
|
158
|
+
# 4. Start server with generated configuration
|
159
|
+
python -m mcp_proxy_adapter --config configs/http_simple.json
|
160
|
+
```
|
161
|
+
|
82
162
|
## Development
|
83
163
|
|
84
164
|
The project follows a modular architecture:
|
{mcp_proxy_adapter-6.4.44 → mcp_proxy_adapter-6.4.45}/mcp_proxy_adapter/core/proxy_registration.py
RENAMED
@@ -68,84 +68,116 @@ class ProxyRegistrationManager:
|
|
68
68
|
except Exception:
|
69
69
|
pass
|
70
70
|
|
71
|
-
#
|
72
|
-
self.
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
self.server_id = self.registration_config.get("server_id")
|
79
|
-
if not self.server_id:
|
80
|
-
# Try to get from proxy_info.name as fallback
|
81
|
-
self.server_id = self.registration_config.get("proxy_info", {}).get("name")
|
82
|
-
if not self.server_id:
|
71
|
+
# Check if registration is enabled
|
72
|
+
self.enabled = self.registration_config.get("enabled", False)
|
73
|
+
|
74
|
+
# Basic registration settings - only validate if enabled
|
75
|
+
if self.enabled:
|
76
|
+
self.proxy_url = self.registration_config.get("proxy_url")
|
77
|
+
if not self.proxy_url:
|
83
78
|
raise ValueError(
|
84
|
-
"
|
85
|
-
"Please specify a
|
79
|
+
"proxy_url is required in registration configuration. "
|
80
|
+
"Please specify a valid proxy URL in your configuration."
|
86
81
|
)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
82
|
+
else:
|
83
|
+
self.proxy_url = None
|
84
|
+
|
85
|
+
if self.enabled:
|
86
|
+
self.server_id = self.registration_config.get("server_id")
|
87
|
+
if not self.server_id:
|
88
|
+
# Try to get from proxy_info.name as fallback
|
89
|
+
self.server_id = self.registration_config.get("proxy_info", {}).get("name")
|
90
|
+
if not self.server_id:
|
91
|
+
raise ValueError(
|
92
|
+
"server_id is required in registration configuration. "
|
93
|
+
"Please specify a server_id or proxy_info.name in your configuration."
|
94
|
+
)
|
95
|
+
self.server_name = self.registration_config.get("server_name")
|
91
96
|
if not self.server_name:
|
97
|
+
# Try to get from proxy_info.name as fallback
|
98
|
+
self.server_name = self.registration_config.get("proxy_info", {}).get("name")
|
99
|
+
if not self.server_name:
|
100
|
+
raise ValueError(
|
101
|
+
"server_name is required in registration configuration. "
|
102
|
+
"Please specify a server_name or proxy_info.name in your configuration."
|
103
|
+
)
|
104
|
+
self.description = self.registration_config.get("description")
|
105
|
+
if not self.description:
|
106
|
+
# Try to get from proxy_info.description as fallback
|
107
|
+
self.description = self.registration_config.get("proxy_info", {}).get("description")
|
108
|
+
if not self.description:
|
109
|
+
raise ValueError(
|
110
|
+
"description is required in registration configuration. "
|
111
|
+
"Please specify a description or proxy_info.description in your configuration."
|
112
|
+
)
|
113
|
+
else:
|
114
|
+
self.server_id = None
|
115
|
+
self.server_name = None
|
116
|
+
self.description = None
|
117
|
+
|
118
|
+
if self.enabled:
|
119
|
+
self.version = self.registration_config.get("version")
|
120
|
+
if not self.version:
|
121
|
+
# Try to get from proxy_info.version as fallback
|
122
|
+
self.version = self.registration_config.get("proxy_info", {}).get("version")
|
123
|
+
if not self.version:
|
124
|
+
raise ValueError(
|
125
|
+
"version is required in registration configuration. "
|
126
|
+
"Please specify a version or proxy_info.version in your configuration."
|
127
|
+
)
|
128
|
+
else:
|
129
|
+
self.version = None
|
130
|
+
|
131
|
+
# Heartbeat settings - only validate if enabled
|
132
|
+
if self.enabled:
|
133
|
+
heartbeat_config = self.registration_config.get("heartbeat", {})
|
134
|
+
self.timeout = heartbeat_config.get("timeout")
|
135
|
+
if self.timeout is None:
|
92
136
|
raise ValueError(
|
93
|
-
"
|
94
|
-
"Please specify a
|
137
|
+
"heartbeat.timeout is required in registration configuration. "
|
138
|
+
"Please specify a timeout value."
|
95
139
|
)
|
96
|
-
|
97
|
-
|
98
|
-
# Try to get from proxy_info.description as fallback
|
99
|
-
self.description = self.registration_config.get("proxy_info", {}).get("description")
|
100
|
-
if not self.description:
|
140
|
+
self.retry_attempts = heartbeat_config.get("retry_attempts")
|
141
|
+
if self.retry_attempts is None:
|
101
142
|
raise ValueError(
|
102
|
-
"
|
103
|
-
"Please specify a
|
143
|
+
"heartbeat.retry_attempts is required in registration configuration. "
|
144
|
+
"Please specify a retry_attempts value."
|
104
145
|
)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
146
|
+
else:
|
147
|
+
self.timeout = None
|
148
|
+
self.retry_attempts = None
|
149
|
+
|
150
|
+
if self.enabled:
|
151
|
+
self.retry_delay = heartbeat_config.get("retry_delay")
|
152
|
+
if self.retry_delay is None:
|
110
153
|
raise ValueError(
|
111
|
-
"
|
112
|
-
"Please specify a
|
154
|
+
"heartbeat.retry_delay is required in registration configuration. "
|
155
|
+
"Please specify a retry_delay value."
|
113
156
|
)
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
self.
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
"heartbeat.retry_attempts is required in registration configuration. "
|
127
|
-
"Please specify a retry_attempts value."
|
128
|
-
)
|
129
|
-
self.retry_delay = heartbeat_config.get("retry_delay")
|
130
|
-
if self.retry_delay is None:
|
131
|
-
raise ValueError(
|
132
|
-
"heartbeat.retry_delay is required in registration configuration. "
|
133
|
-
"Please specify a retry_delay value."
|
134
|
-
)
|
135
|
-
self.heartbeat_interval = heartbeat_config.get("interval")
|
136
|
-
if self.heartbeat_interval is None:
|
137
|
-
raise ValueError(
|
138
|
-
"heartbeat.interval is required in registration configuration. "
|
139
|
-
"Please specify an interval value."
|
140
|
-
)
|
157
|
+
else:
|
158
|
+
self.retry_delay = None
|
159
|
+
|
160
|
+
if self.enabled:
|
161
|
+
self.heartbeat_interval = heartbeat_config.get("interval")
|
162
|
+
if self.heartbeat_interval is None:
|
163
|
+
raise ValueError(
|
164
|
+
"heartbeat.interval is required in registration configuration. "
|
165
|
+
"Please specify an interval value."
|
166
|
+
)
|
167
|
+
else:
|
168
|
+
self.heartbeat_interval = None
|
141
169
|
|
142
170
|
# Auto registration settings
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
171
|
+
if self.enabled:
|
172
|
+
self.auto_register = self.registration_config.get("enabled")
|
173
|
+
if self.auto_register is None:
|
174
|
+
raise ValueError(
|
175
|
+
"enabled is required in registration configuration. "
|
176
|
+
"Please specify whether registration is enabled (true/false)."
|
177
|
+
)
|
178
|
+
else:
|
179
|
+
self.auto_register = False
|
180
|
+
|
149
181
|
self.auto_unregister = True # Always unregister on shutdown
|
150
182
|
|
151
183
|
# Initialize client security manager
|
@@ -168,7 +200,7 @@ class ProxyRegistrationManager:
|
|
168
200
|
Returns:
|
169
201
|
True if registration is enabled, False otherwise.
|
170
202
|
"""
|
171
|
-
return self.
|
203
|
+
return self.enabled
|
172
204
|
|
173
205
|
def set_server_url(self, server_url: str) -> None:
|
174
206
|
"""
|
@@ -0,0 +1,284 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Bugfix for mcp_security_framework CertificateConfig
|
4
|
+
This script provides a fix for the CertificateConfig validation issue.
|
5
|
+
|
6
|
+
ISSUE: CertificateConfig requires CA certificate and key paths even when creating a CA certificate.
|
7
|
+
This creates a chicken-and-egg problem where you need a CA to create a CA.
|
8
|
+
|
9
|
+
SOLUTION: Modify the validation logic to allow CA creation mode.
|
10
|
+
|
11
|
+
Author: Vasiliy Zdanovskiy
|
12
|
+
email: vasilyvz@gmail.com
|
13
|
+
"""
|
14
|
+
|
15
|
+
import sys
|
16
|
+
from pathlib import Path
|
17
|
+
from typing import Optional
|
18
|
+
from pydantic import BaseModel, Field, field_validator, model_validator
|
19
|
+
|
20
|
+
|
21
|
+
class FixedCertificateConfig(BaseModel):
|
22
|
+
"""
|
23
|
+
Fixed Certificate Management Configuration Model
|
24
|
+
|
25
|
+
This model defines certificate management configuration settings
|
26
|
+
including CA settings, certificate storage, and validation options.
|
27
|
+
|
28
|
+
BUGFIX: Added ca_creation_mode to allow CA certificate creation
|
29
|
+
without requiring existing CA paths.
|
30
|
+
|
31
|
+
Attributes:
|
32
|
+
enabled: Whether certificate management is enabled
|
33
|
+
ca_creation_mode: Whether we are in CA creation mode (bypasses CA path validation)
|
34
|
+
ca_cert_path: Path to CA certificate
|
35
|
+
ca_key_path: Path to CA private key
|
36
|
+
cert_storage_path: Path for certificate storage
|
37
|
+
key_storage_path: Path for private key storage
|
38
|
+
default_validity_days: Default certificate validity in days
|
39
|
+
key_size: RSA key size for generated certificates
|
40
|
+
hash_algorithm: Hash algorithm for certificate signing
|
41
|
+
crl_enabled: Whether CRL is enabled
|
42
|
+
crl_path: Path for CRL storage
|
43
|
+
crl_validity_days: CRL validity period in days
|
44
|
+
auto_renewal: Whether automatic certificate renewal is enabled
|
45
|
+
renewal_threshold_days: Days before expiry to renew
|
46
|
+
"""
|
47
|
+
|
48
|
+
enabled: bool = Field(
|
49
|
+
default=False, description="Whether certificate management is enabled"
|
50
|
+
)
|
51
|
+
ca_creation_mode: bool = Field(
|
52
|
+
default=False, description="Whether we are in CA creation mode (bypasses CA path validation)"
|
53
|
+
)
|
54
|
+
ca_cert_path: Optional[str] = Field(
|
55
|
+
default=None, description="Path to CA certificate"
|
56
|
+
)
|
57
|
+
ca_key_path: Optional[str] = Field(
|
58
|
+
default=None, description="Path to CA private key"
|
59
|
+
)
|
60
|
+
cert_storage_path: str = Field(
|
61
|
+
default="./certs", description="Path for certificate storage"
|
62
|
+
)
|
63
|
+
key_storage_path: str = Field(
|
64
|
+
default="./keys", description="Path for private key storage"
|
65
|
+
)
|
66
|
+
default_validity_days: int = Field(
|
67
|
+
default=365, ge=1, le=3650, description="Default certificate validity in days"
|
68
|
+
)
|
69
|
+
key_size: int = Field(
|
70
|
+
default=2048,
|
71
|
+
ge=1024,
|
72
|
+
le=4096,
|
73
|
+
description="RSA key size for generated certificates",
|
74
|
+
)
|
75
|
+
hash_algorithm: str = Field(
|
76
|
+
default="sha256", description="Hash algorithm for certificate signing"
|
77
|
+
)
|
78
|
+
crl_enabled: bool = Field(default=False, description="Whether CRL is enabled")
|
79
|
+
crl_path: Optional[str] = Field(default=None, description="Path for CRL storage")
|
80
|
+
crl_validity_days: int = Field(
|
81
|
+
default=30, ge=1, le=365, description="CRL validity period in days"
|
82
|
+
)
|
83
|
+
auto_renewal: bool = Field(
|
84
|
+
default=False, description="Whether automatic certificate renewal is enabled"
|
85
|
+
)
|
86
|
+
renewal_threshold_days: int = Field(
|
87
|
+
default=30, ge=1, le=90, description="Days before expiry to renew"
|
88
|
+
)
|
89
|
+
|
90
|
+
@field_validator("hash_algorithm")
|
91
|
+
@classmethod
|
92
|
+
def validate_hash_algorithm(cls, v):
|
93
|
+
"""Validate hash algorithm."""
|
94
|
+
valid_algorithms = ["sha1", "sha256", "sha384", "sha512"]
|
95
|
+
if v not in valid_algorithms:
|
96
|
+
raise ValueError(
|
97
|
+
f"Invalid hash algorithm. Must be one of: {valid_algorithms}"
|
98
|
+
)
|
99
|
+
return v
|
100
|
+
|
101
|
+
@model_validator(mode="after")
|
102
|
+
def validate_certificate_configuration(self):
|
103
|
+
"""Validate certificate configuration consistency."""
|
104
|
+
if self.enabled:
|
105
|
+
# BUGFIX: Only require CA paths if not in CA creation mode
|
106
|
+
if not self.ca_creation_mode:
|
107
|
+
if not self.ca_cert_path or not self.ca_key_path:
|
108
|
+
raise ValueError(
|
109
|
+
"Certificate management enabled but CA certificate and key paths are required. "
|
110
|
+
"Set ca_creation_mode=True if you are creating a CA certificate."
|
111
|
+
)
|
112
|
+
|
113
|
+
if self.crl_enabled and not self.crl_path:
|
114
|
+
raise ValueError("CRL enabled but CRL path is required")
|
115
|
+
|
116
|
+
return self
|
117
|
+
|
118
|
+
|
119
|
+
def create_patch_file():
|
120
|
+
"""Create a patch file for the mcp_security_framework."""
|
121
|
+
|
122
|
+
patch_content = '''--- a/mcp_security_framework/schemas/config.py
|
123
|
+
+++ b/mcp_security_framework/schemas/config.py
|
124
|
+
@@ -1,6 +1,7 @@
|
125
|
+
from typing import Optional
|
126
|
+
from pydantic import BaseModel, Field, field_validator, model_validator
|
127
|
+
|
128
|
+
+
|
129
|
+
class CertificateConfig(BaseModel):
|
130
|
+
"""
|
131
|
+
Certificate Management Configuration Model
|
132
|
+
@@ -8,6 +9,7 @@ class CertificateConfig(BaseModel):
|
133
|
+
This model defines certificate management configuration settings
|
134
|
+
including CA settings, certificate storage, and validation options.
|
135
|
+
|
136
|
+
+ BUGFIX: Added ca_creation_mode to allow CA certificate creation
|
137
|
+
Attributes:
|
138
|
+
enabled: Whether certificate management is enabled
|
139
|
+
ca_cert_path: Path to CA certificate
|
140
|
+
@@ -20,6 +22,9 @@ class CertificateConfig(BaseModel):
|
141
|
+
enabled: bool = Field(
|
142
|
+
default=False, description="Whether certificate management is enabled"
|
143
|
+
)
|
144
|
+
+ ca_creation_mode: bool = Field(
|
145
|
+
+ default=False, description="Whether we are in CA creation mode (bypasses CA path validation)"
|
146
|
+
+ )
|
147
|
+
ca_cert_path: Optional[str] = Field(
|
148
|
+
default=None, description="Path to CA certificate"
|
149
|
+
)
|
150
|
+
@@ -60,7 +65,9 @@ class CertificateConfig(BaseModel):
|
151
|
+
@model_validator(mode="after")
|
152
|
+
def validate_certificate_configuration(self):
|
153
|
+
"""Validate certificate configuration consistency."""
|
154
|
+
if self.enabled:
|
155
|
+
- if not self.ca_cert_path or not self.ca_key_path:
|
156
|
+
- raise ValueError(
|
157
|
+
- "Certificate management enabled but CA certificate and key paths are required"
|
158
|
+
- )
|
159
|
+
+ # BUGFIX: Only require CA paths if not in CA creation mode
|
160
|
+
+ if not self.ca_creation_mode:
|
161
|
+
+ if not self.ca_cert_path or not self.ca_key_path:
|
162
|
+
+ raise ValueError(
|
163
|
+
+ "Certificate management enabled but CA certificate and key paths are required. "
|
164
|
+
+ "Set ca_creation_mode=True if you are creating a CA certificate."
|
165
|
+
+ )
|
166
|
+
|
167
|
+
if self.crl_enabled and not self.crl_path:
|
168
|
+
raise ValueError("CRL enabled but CRL path is required")
|
169
|
+
|
170
|
+
return self
|
171
|
+
'''
|
172
|
+
|
173
|
+
patch_file = Path("certificate_config_bugfix.patch")
|
174
|
+
with open(patch_file, 'w') as f:
|
175
|
+
f.write(patch_content)
|
176
|
+
|
177
|
+
print(f"✅ Patch file created: {patch_file}")
|
178
|
+
return patch_file
|
179
|
+
|
180
|
+
|
181
|
+
def test_fixed_config():
|
182
|
+
"""Test the fixed configuration."""
|
183
|
+
print("🧪 Testing Fixed CertificateConfig")
|
184
|
+
print("=" * 50)
|
185
|
+
|
186
|
+
# Test 1: CA creation mode should work without CA paths
|
187
|
+
print("Test 1: CA creation mode")
|
188
|
+
try:
|
189
|
+
config1 = FixedCertificateConfig(
|
190
|
+
enabled=True,
|
191
|
+
ca_creation_mode=True,
|
192
|
+
cert_storage_path="./certs",
|
193
|
+
key_storage_path="./keys"
|
194
|
+
)
|
195
|
+
print("✅ CA creation mode works correctly")
|
196
|
+
except Exception as e:
|
197
|
+
print(f"❌ CA creation mode failed: {e}")
|
198
|
+
return False
|
199
|
+
|
200
|
+
# Test 2: Normal mode should require CA paths
|
201
|
+
print("Test 2: Normal mode without CA paths")
|
202
|
+
try:
|
203
|
+
config2 = FixedCertificateConfig(
|
204
|
+
enabled=True,
|
205
|
+
ca_creation_mode=False,
|
206
|
+
cert_storage_path="./certs",
|
207
|
+
key_storage_path="./keys"
|
208
|
+
)
|
209
|
+
print("❌ Normal mode should have failed without CA paths")
|
210
|
+
return False
|
211
|
+
except ValueError as e:
|
212
|
+
print("✅ Normal mode correctly requires CA paths")
|
213
|
+
except Exception as e:
|
214
|
+
print(f"❌ Unexpected error: {e}")
|
215
|
+
return False
|
216
|
+
|
217
|
+
# Test 3: Normal mode with CA paths should work
|
218
|
+
print("Test 3: Normal mode with CA paths")
|
219
|
+
try:
|
220
|
+
config3 = FixedCertificateConfig(
|
221
|
+
enabled=True,
|
222
|
+
ca_creation_mode=False,
|
223
|
+
ca_cert_path="./certs/ca.crt",
|
224
|
+
ca_key_path="./keys/ca.key",
|
225
|
+
cert_storage_path="./certs",
|
226
|
+
key_storage_path="./keys"
|
227
|
+
)
|
228
|
+
print("✅ Normal mode with CA paths works correctly")
|
229
|
+
except Exception as e:
|
230
|
+
print(f"❌ Normal mode with CA paths failed: {e}")
|
231
|
+
return False
|
232
|
+
|
233
|
+
print("\n🎉 All tests passed!")
|
234
|
+
return True
|
235
|
+
|
236
|
+
|
237
|
+
def main():
|
238
|
+
"""Main entry point."""
|
239
|
+
print("🔧 mcp_security_framework CertificateConfig Bugfix")
|
240
|
+
print("=" * 60)
|
241
|
+
print()
|
242
|
+
print("ISSUE DESCRIPTION:")
|
243
|
+
print("CertificateConfig requires CA certificate and key paths even when")
|
244
|
+
print("creating a CA certificate. This creates a chicken-and-egg problem.")
|
245
|
+
print()
|
246
|
+
print("SOLUTION:")
|
247
|
+
print("Add ca_creation_mode field to bypass CA path validation when")
|
248
|
+
print("creating a CA certificate.")
|
249
|
+
print()
|
250
|
+
|
251
|
+
# Test the fix
|
252
|
+
if test_fixed_config():
|
253
|
+
# Create patch file
|
254
|
+
patch_file = create_patch_file()
|
255
|
+
print(f"\n📁 To apply this fix to mcp_security_framework:")
|
256
|
+
print(f" 1. Copy the patch file to the framework directory")
|
257
|
+
print(f" 2. Run: patch -p1 < {patch_file}")
|
258
|
+
print(f" 3. Or manually apply the changes shown in the patch")
|
259
|
+
print()
|
260
|
+
print("🔧 USAGE EXAMPLE:")
|
261
|
+
print(" # For CA creation:")
|
262
|
+
print(" config = CertificateConfig(")
|
263
|
+
print(" enabled=True,")
|
264
|
+
print(" ca_creation_mode=True, # <-- This is the fix")
|
265
|
+
print(" cert_storage_path='./certs',")
|
266
|
+
print(" key_storage_path='./keys'")
|
267
|
+
print(" )")
|
268
|
+
print()
|
269
|
+
print(" # For normal certificate creation:")
|
270
|
+
print(" config = CertificateConfig(")
|
271
|
+
print(" enabled=True,")
|
272
|
+
print(" ca_creation_mode=False,")
|
273
|
+
print(" ca_cert_path='./certs/ca.crt',")
|
274
|
+
print(" ca_key_path='./keys/ca.key'")
|
275
|
+
print(" )")
|
276
|
+
else:
|
277
|
+
print("❌ Tests failed!")
|
278
|
+
return 1
|
279
|
+
|
280
|
+
return 0
|
281
|
+
|
282
|
+
|
283
|
+
if __name__ == "__main__":
|
284
|
+
sys.exit(main())
|