mcp-proxy-adapter 6.8.2__tar.gz → 6.9.1__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.8.2 → mcp_proxy_adapter-6.9.1}/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/config.py +208 -110
- mcp_proxy_adapter-6.9.1/mcp_proxy_adapter/core/config_validator.py +1106 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/errors.py +42 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/logging.py +16 -16
- mcp_proxy_adapter-6.9.1/mcp_proxy_adapter/examples/config_builder.py +217 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/main.py +10 -2
- mcp_proxy_adapter-6.9.1/mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter-6.9.1/mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter-6.9.1/mcp_proxy_adapter/examples/full_application/test_server.py +221 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/generate_config.py +61 -8
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_config.py +47 -2
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/SOURCES.txt +15 -1
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/pyproject.toml +1 -1
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/setup.py +13 -3
- mcp_proxy_adapter-6.9.1/tests/test_certificate_validation.py +345 -0
- mcp_proxy_adapter-6.9.1/tests/test_config_integration.py +287 -0
- mcp_proxy_adapter-6.9.1/tests/test_config_validation.py +491 -0
- mcp_proxy_adapter-6.9.1/tests/test_config_validation_isolated.py +458 -0
- mcp_proxy_adapter-6.9.1/tests/test_direct_import.py +87 -0
- mcp_proxy_adapter-6.9.1/tests/test_isolated_validation.py +281 -0
- mcp_proxy_adapter-6.9.1/tests/test_no_defaults.py +313 -0
- mcp_proxy_adapter-6.9.1/tests/test_simple_validation.py +197 -0
- mcp_proxy_adapter-6.8.2/mcp_proxy_adapter/core/config_validator.py +0 -218
- mcp_proxy_adapter-6.8.2/mcp_proxy_adapter/examples/config_builder.py +0 -766
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/README.md +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/__main__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/app.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/handlers.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/base.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/error_handling.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/factory.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/logging.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/performance.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/protocol_middleware.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/unified_security.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/schemas.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/tool_integration.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/api/tools.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/auth_validation_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/base.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/builtin_commands.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/catalog_manager.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/cert_monitor_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/certificate_management_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/command_registry.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/config_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/dependency_container.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/dependency_manager.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/echo_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/health_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/help_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/hooks.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/key_management_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/load_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/plugins_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/protocol_management_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/proxy_registration_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/registration_status_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/reload_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/result.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/role_test_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/roles_management_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/security_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/settings_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/ssl_setup_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/token_management_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/transport_management_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/commands/unload_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/app_factory.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/app_runner.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/auth_validator.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/certificate_utils.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/client.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/client_manager.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/client_security.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/config_converter.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/crl_utils.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/mtls_asgi.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/mtls_asgi_app.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/mtls_proxy.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/mtls_server.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/protocol_manager.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/proxy_client.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/proxy_registration.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/role_utils.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/security_adapter.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/security_factory.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/security_integration.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/server_adapter.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/server_engine.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/settings.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/signal_handler.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/ssl_utils.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/transport_manager.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/unified_config_adapter.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/core/utils.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/custom_openapi.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/basic_framework/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/basic_framework/main.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/cert_manager_bugfix.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/check_config.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/config_cli.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/create_test_configs.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/debug_request_state.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/debug_role_chain.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/demo_client.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/proxy_registration_example.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/required_certificates.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/run_example.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/run_full_test_suite.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/run_proxy_server.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/security_test_client.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/setup_test_environment.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/simple_protocol_test.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_chk_hostname_automated.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_config_builder.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_examples.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_framework_complete.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_mcp_server.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/test_protocol_examples.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/universal_client.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/examples/update_config_certificates.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/main.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/openapi.py +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/schemas/base_schema.json +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/schemas/openapi_schema.json +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/schemas/roles.json +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter/schemas/roles_schema.json +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/dependency_links.txt +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/not-zip-safe +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/requires.txt +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/mcp_proxy_adapter.egg-info/top_level.txt +0 -0
- {mcp_proxy_adapter-6.8.2 → mcp_proxy_adapter-6.9.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-proxy-adapter
|
3
|
-
Version: 6.
|
3
|
+
Version: 6.9.1
|
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
|
@@ -12,6 +12,17 @@ from typing import Any, Dict, Optional, List
|
|
12
12
|
|
13
13
|
logger = logging.getLogger(__name__)
|
14
14
|
|
15
|
+
# Import validation if available
|
16
|
+
try:
|
17
|
+
from .core.config_validator import ConfigValidator, ValidationResult, ValidationLevel
|
18
|
+
VALIDATION_AVAILABLE = True
|
19
|
+
except ImportError:
|
20
|
+
VALIDATION_AVAILABLE = False
|
21
|
+
logger.warning("Configuration validation not available. Install the package to enable validation.")
|
22
|
+
|
23
|
+
# Import configuration errors
|
24
|
+
from .core.errors import ConfigError, ValidationResult
|
25
|
+
|
15
26
|
|
16
27
|
class Config:
|
17
28
|
"""
|
@@ -20,113 +31,64 @@ class Config:
|
|
20
31
|
Supports optional features that can be enabled/disabled.
|
21
32
|
"""
|
22
33
|
|
23
|
-
def __init__(self, config_path: Optional[str] = None):
|
34
|
+
def __init__(self, config_path: Optional[str] = None, validate_on_load: bool = True):
|
24
35
|
"""
|
25
36
|
Initialize configuration.
|
26
37
|
|
27
38
|
Args:
|
28
39
|
config_path: Path to configuration file. If not specified,
|
29
40
|
"./config.json" is used.
|
41
|
+
validate_on_load: Whether to validate configuration on load (default: True)
|
42
|
+
|
43
|
+
Raises:
|
44
|
+
ConfigError: If configuration validation fails
|
30
45
|
"""
|
31
46
|
self.config_path = config_path or "./config.json"
|
32
47
|
self.config_data: Dict[str, Any] = {}
|
48
|
+
self.validate_on_load = validate_on_load
|
49
|
+
self.validation_results: List[ValidationResult] = []
|
50
|
+
self.validator = None
|
51
|
+
|
52
|
+
if VALIDATION_AVAILABLE:
|
53
|
+
self.validator = ConfigValidator()
|
54
|
+
|
33
55
|
self.load_config()
|
34
56
|
|
35
57
|
def load_config(self) -> None:
|
36
58
|
"""
|
37
59
|
Load configuration from file and environment variables.
|
60
|
+
NO DEFAULT VALUES - configuration must be complete and valid.
|
38
61
|
"""
|
39
|
-
#
|
40
|
-
self.
|
41
|
-
"
|
42
|
-
|
43
|
-
|
44
|
-
"protocol": "http",
|
45
|
-
"debug": False,
|
46
|
-
"log_level": "INFO",
|
47
|
-
},
|
48
|
-
"logging": {
|
49
|
-
"level": "INFO",
|
50
|
-
"file": None,
|
51
|
-
"log_dir": "./logs",
|
52
|
-
"log_file": "mcp_proxy_adapter.log",
|
53
|
-
"error_log_file": "mcp_proxy_adapter_error.log",
|
54
|
-
"access_log_file": "mcp_proxy_adapter_access.log",
|
55
|
-
"max_file_size": "10MB",
|
56
|
-
"backup_count": 5,
|
57
|
-
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
58
|
-
"date_format": "%Y-%m-%d %H:%M:%S",
|
59
|
-
"console_output": True,
|
60
|
-
"file_output": True,
|
61
|
-
},
|
62
|
-
"commands": {
|
63
|
-
"auto_discovery": True,
|
64
|
-
"commands_directory": "./commands",
|
65
|
-
"catalog_directory": "./catalog",
|
66
|
-
"plugin_servers": [],
|
67
|
-
"auto_install_dependencies": True,
|
68
|
-
"enabled_commands": ["health", "echo", "list", "help"],
|
69
|
-
"disabled_commands": [],
|
70
|
-
"custom_commands_path": "./commands",
|
71
|
-
},
|
72
|
-
"roles": {
|
73
|
-
"enabled": False,
|
74
|
-
"config_file": None,
|
75
|
-
"default_policy": {
|
76
|
-
"deny_by_default": False,
|
77
|
-
"require_role_match": False,
|
78
|
-
"case_sensitive": False,
|
79
|
-
"allow_wildcard": False,
|
80
|
-
},
|
81
|
-
"auto_load": False,
|
82
|
-
"validation_enabled": False,
|
83
|
-
},
|
84
|
-
"transport": {
|
85
|
-
"type": "http",
|
86
|
-
"port": None,
|
87
|
-
"verify_client": False,
|
88
|
-
"chk_hostname": False, # Default to False for HTTP
|
89
|
-
},
|
90
|
-
"proxy_registration": {
|
91
|
-
"enabled": False,
|
92
|
-
"proxy_url": "http://localhost:3004",
|
93
|
-
"server_id": "mcp_proxy_adapter",
|
94
|
-
"server_name": "MCP Proxy Adapter",
|
95
|
-
"description": "JSON-RPC API for interacting with MCP Proxy",
|
96
|
-
"version": "6.2.33",
|
97
|
-
"registration_timeout": 30,
|
98
|
-
"retry_attempts": 3,
|
99
|
-
"retry_delay": 5,
|
100
|
-
"auto_register_on_startup": True,
|
101
|
-
"auto_unregister_on_shutdown": True,
|
102
|
-
},
|
103
|
-
"debug": {"enabled": False, "level": "WARNING"},
|
104
|
-
"security": {
|
105
|
-
"enabled": False,
|
106
|
-
"tokens": {
|
107
|
-
"admin": "admin-secret-key",
|
108
|
-
"user": "user-secret-key",
|
109
|
-
"readonly": "readonly-secret-key"
|
110
|
-
},
|
111
|
-
"roles": {
|
112
|
-
"admin": ["read", "write", "delete", "admin"],
|
113
|
-
"user": ["read", "write"],
|
114
|
-
"readonly": ["read"]
|
115
|
-
},
|
116
|
-
"roles_file": None
|
117
|
-
},
|
118
|
-
}
|
119
|
-
|
120
|
-
# Try to load configuration from file
|
121
|
-
if os.path.exists(self.config_path):
|
122
|
-
try:
|
62
|
+
# Load configuration from file - NO DEFAULTS
|
63
|
+
if not os.path.exists(self.config_path):
|
64
|
+
raise ConfigError(f"Configuration file '{self.config_path}' does not exist. Use the configuration generator to create a valid configuration.")
|
65
|
+
|
66
|
+
try:
|
123
67
|
with open(self.config_path, "r", encoding="utf-8") as f:
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
68
|
+
self.config_data = json.load(f)
|
69
|
+
except json.JSONDecodeError as e:
|
70
|
+
raise ConfigError(f"Configuration file '{self.config_path}' contains invalid JSON: {e}")
|
71
|
+
except Exception as e:
|
72
|
+
raise ConfigError(f"Error loading configuration from '{self.config_path}': {e}")
|
73
|
+
|
74
|
+
# Validate configuration BEFORE applying any logic
|
75
|
+
if self.validate_on_load:
|
76
|
+
if VALIDATION_AVAILABLE and self.validator:
|
77
|
+
self.validator.config_data = self.config_data
|
78
|
+
validation_results = self.validator.validate_config()
|
79
|
+
|
80
|
+
# Check for critical errors
|
81
|
+
errors = [r for r in validation_results if r.level == "error"]
|
82
|
+
if errors:
|
83
|
+
error_summary = "\n".join([f"[{r.section}.{r.key if r.key else 'root'}] {r.message}" for r in errors])
|
84
|
+
raise ConfigError(f"Configuration validation failed with {len(errors)} error(s):\n{error_summary}", errors)
|
85
|
+
|
86
|
+
# Store validation results for later access
|
87
|
+
self.validation_results = validation_results
|
88
|
+
else:
|
89
|
+
raise ConfigError("Configuration validation is not available. Install required dependencies.")
|
90
|
+
|
91
|
+
# Load configuration from environment variables (overrides file values)
|
130
92
|
self._load_env_variables()
|
131
93
|
|
132
94
|
# Apply hostname check logic based on SSL configuration
|
@@ -257,23 +219,6 @@ class Config:
|
|
257
219
|
with open(save_path, "w", encoding="utf-8") as f:
|
258
220
|
json.dump(self.config_data, f, indent=2)
|
259
221
|
|
260
|
-
def _update_nested_dict(self, d: Dict, u: Dict) -> Dict:
|
261
|
-
"""
|
262
|
-
Update nested dictionary recursively.
|
263
|
-
|
264
|
-
Args:
|
265
|
-
d: Dictionary to update
|
266
|
-
u: Dictionary with new values
|
267
|
-
|
268
|
-
Returns:
|
269
|
-
Updated dictionary
|
270
|
-
"""
|
271
|
-
for k, v in u.items():
|
272
|
-
if isinstance(v, dict) and k in d and isinstance(d[k], dict):
|
273
|
-
self._update_nested_dict(d[k], v)
|
274
|
-
else:
|
275
|
-
d[k] = v
|
276
|
-
return d
|
277
222
|
|
278
223
|
def enable_feature(self, feature: str) -> None:
|
279
224
|
"""
|
@@ -540,6 +485,159 @@ class Config:
|
|
540
485
|
chk_hostname_value = self.get("transport.ssl.chk_hostname")
|
541
486
|
logger.debug(f"Using explicitly set chk_hostname={chk_hostname_value} for protocol {protocol}")
|
542
487
|
|
488
|
+
def validate(self) -> List[ValidationResult]:
|
489
|
+
"""
|
490
|
+
Validate current configuration.
|
491
|
+
|
492
|
+
Returns:
|
493
|
+
List of validation results
|
494
|
+
|
495
|
+
Raises:
|
496
|
+
ConfigError: If validation is not available or critical errors are found
|
497
|
+
"""
|
498
|
+
if not VALIDATION_AVAILABLE:
|
499
|
+
raise ConfigError("Configuration validation is not available. Please install the package properly.")
|
500
|
+
|
501
|
+
if not self.validator:
|
502
|
+
self.validator = ConfigValidator()
|
503
|
+
|
504
|
+
self.validator.config_data = self.config_data
|
505
|
+
self.validation_results = self.validator.validate_config()
|
506
|
+
|
507
|
+
# Log validation results
|
508
|
+
for result in self.validation_results:
|
509
|
+
if result.level == ValidationLevel.ERROR:
|
510
|
+
logger.error(f"Configuration error: {result.message}")
|
511
|
+
elif result.level == ValidationLevel.WARNING:
|
512
|
+
logger.warning(f"Configuration warning: {result.message}")
|
513
|
+
else:
|
514
|
+
logger.info(f"Configuration info: {result.message}")
|
515
|
+
|
516
|
+
# Raise ConfigError if there are critical errors
|
517
|
+
errors = [r for r in self.validation_results if r.level == ValidationLevel.ERROR]
|
518
|
+
if errors:
|
519
|
+
error_summary = "\n".join([f"[{r.section}.{r.key if r.key else 'root'}] {r.message}" for r in errors])
|
520
|
+
raise ConfigError(f"Configuration validation failed with {len(errors)} error(s):\n{error_summary}", errors)
|
521
|
+
|
522
|
+
return self.validation_results
|
523
|
+
|
524
|
+
def is_valid(self) -> bool:
|
525
|
+
"""Check if configuration is valid."""
|
526
|
+
if not VALIDATION_AVAILABLE:
|
527
|
+
return True
|
528
|
+
|
529
|
+
return all(result.level != ValidationLevel.ERROR for result in self.validation_results)
|
530
|
+
|
531
|
+
def get_validation_errors(self) -> List[ValidationResult]:
|
532
|
+
"""Get all validation errors."""
|
533
|
+
return [r for r in self.validation_results if r.level == ValidationLevel.ERROR]
|
534
|
+
|
535
|
+
def get_validation_warnings(self) -> List[ValidationResult]:
|
536
|
+
"""Get all validation warnings."""
|
537
|
+
return [r for r in self.validation_results if r.level == ValidationLevel.WARNING]
|
538
|
+
|
539
|
+
def get_validation_summary(self) -> Dict[str, Any]:
|
540
|
+
"""Get validation summary."""
|
541
|
+
if not VALIDATION_AVAILABLE or not self.validator:
|
542
|
+
return {"total_issues": 0, "errors": 0, "warnings": 0, "info": 0, "is_valid": True}
|
543
|
+
|
544
|
+
return self.validator.get_validation_summary()
|
545
|
+
|
546
|
+
def print_validation_report(self) -> None:
|
547
|
+
"""Print detailed validation report."""
|
548
|
+
if not VALIDATION_AVAILABLE or not self.validator:
|
549
|
+
print("Configuration validation not available")
|
550
|
+
return
|
551
|
+
|
552
|
+
self.validator.print_validation_report()
|
553
|
+
|
554
|
+
def check_feature_requirements(self, feature: str) -> List[ValidationResult]:
|
555
|
+
"""Check if all requirements for a feature are met."""
|
556
|
+
if not VALIDATION_AVAILABLE:
|
557
|
+
return []
|
558
|
+
|
559
|
+
results = []
|
560
|
+
|
561
|
+
if feature == "security":
|
562
|
+
if self.get("security.enabled", False):
|
563
|
+
tokens = self.get("security.tokens", {})
|
564
|
+
roles = self.get("security.roles", {})
|
565
|
+
roles_file = self.get("security.roles_file")
|
566
|
+
|
567
|
+
has_tokens = bool(tokens and any(tokens.values()))
|
568
|
+
has_roles = bool(roles and any(roles.values()))
|
569
|
+
has_roles_file = bool(roles_file and os.path.exists(roles_file))
|
570
|
+
|
571
|
+
if not (has_tokens or has_roles or has_roles_file):
|
572
|
+
results.append(ValidationResult(
|
573
|
+
level=ValidationLevel.WARNING,
|
574
|
+
message="Security is enabled but no authentication methods are configured",
|
575
|
+
section="security",
|
576
|
+
suggestion="Configure tokens, roles, or roles_file"
|
577
|
+
))
|
578
|
+
|
579
|
+
elif feature == "roles":
|
580
|
+
if self.get("roles.enabled", False):
|
581
|
+
config_file = self.get("roles.config_file")
|
582
|
+
if not config_file:
|
583
|
+
results.append(ValidationResult(
|
584
|
+
level=ValidationLevel.ERROR,
|
585
|
+
message="Roles are enabled but config_file is not specified",
|
586
|
+
section="roles",
|
587
|
+
key="config_file"
|
588
|
+
))
|
589
|
+
elif not os.path.exists(config_file):
|
590
|
+
results.append(ValidationResult(
|
591
|
+
level=ValidationLevel.ERROR,
|
592
|
+
message=f"Roles config file '{config_file}' does not exist",
|
593
|
+
section="roles",
|
594
|
+
key="config_file"
|
595
|
+
))
|
596
|
+
|
597
|
+
elif feature == "ssl":
|
598
|
+
if self.get("ssl.enabled", False):
|
599
|
+
cert_file = self.get("ssl.cert_file")
|
600
|
+
key_file = self.get("ssl.key_file")
|
601
|
+
|
602
|
+
if not cert_file:
|
603
|
+
results.append(ValidationResult(
|
604
|
+
level=ValidationLevel.ERROR,
|
605
|
+
message="SSL is enabled but cert_file is not specified",
|
606
|
+
section="ssl",
|
607
|
+
key="cert_file"
|
608
|
+
))
|
609
|
+
elif not os.path.exists(cert_file):
|
610
|
+
results.append(ValidationResult(
|
611
|
+
level=ValidationLevel.ERROR,
|
612
|
+
message=f"SSL certificate file '{cert_file}' does not exist",
|
613
|
+
section="ssl",
|
614
|
+
key="cert_file"
|
615
|
+
))
|
616
|
+
|
617
|
+
if not key_file:
|
618
|
+
results.append(ValidationResult(
|
619
|
+
level=ValidationLevel.ERROR,
|
620
|
+
message="SSL is enabled but key_file is not specified",
|
621
|
+
section="ssl",
|
622
|
+
key="key_file"
|
623
|
+
))
|
624
|
+
elif not os.path.exists(key_file):
|
625
|
+
results.append(ValidationResult(
|
626
|
+
level=ValidationLevel.ERROR,
|
627
|
+
message=f"SSL key file '{key_file}' does not exist",
|
628
|
+
section="ssl",
|
629
|
+
key="key_file"
|
630
|
+
))
|
631
|
+
|
632
|
+
return results
|
633
|
+
|
634
|
+
|
635
|
+
# Singleton instance - will be created when needed
|
636
|
+
config = None
|
543
637
|
|
544
|
-
|
545
|
-
|
638
|
+
def get_config() -> Config:
|
639
|
+
"""Get the global configuration instance."""
|
640
|
+
global config
|
641
|
+
if config is None:
|
642
|
+
config = Config()
|
643
|
+
return config
|