mcp-proxy-adapter 6.0.0__py3-none-any.whl โ 6.1.1__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.
- mcp_proxy_adapter/api/app.py +174 -80
- mcp_proxy_adapter/api/handlers.py +16 -5
- mcp_proxy_adapter/api/middleware/__init__.py +9 -4
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
- mcp_proxy_adapter/api/middleware/factory.py +36 -12
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +32 -13
- mcp_proxy_adapter/api/middleware/unified_security.py +160 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
- mcp_proxy_adapter/commands/__init__.py +7 -1
- mcp_proxy_adapter/commands/base.py +7 -4
- mcp_proxy_adapter/commands/builtin_commands.py +8 -2
- mcp_proxy_adapter/commands/command_registry.py +8 -0
- mcp_proxy_adapter/commands/echo_command.py +81 -0
- mcp_proxy_adapter/commands/help_command.py +21 -14
- mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
- mcp_proxy_adapter/commands/role_test_command.py +141 -0
- mcp_proxy_adapter/commands/security_command.py +488 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +2 -2
- mcp_proxy_adapter/commands/token_management_command.py +1 -1
- mcp_proxy_adapter/config.py +81 -21
- mcp_proxy_adapter/core/app_factory.py +326 -0
- mcp_proxy_adapter/core/client_security.py +384 -0
- mcp_proxy_adapter/core/logging.py +8 -3
- mcp_proxy_adapter/core/mtls_asgi.py +156 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/protocol_manager.py +139 -8
- mcp_proxy_adapter/core/proxy_client.py +602 -0
- mcp_proxy_adapter/core/proxy_registration.py +299 -47
- mcp_proxy_adapter/core/security_adapter.py +12 -15
- mcp_proxy_adapter/core/security_integration.py +285 -0
- mcp_proxy_adapter/core/server_adapter.py +345 -0
- mcp_proxy_adapter/core/server_engine.py +364 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
- mcp_proxy_adapter/docs/EN/TROUBLESHOOTING.md +285 -0
- mcp_proxy_adapter/docs/RU/TROUBLESHOOTING.md +285 -0
- mcp_proxy_adapter/examples/README.md +230 -97
- mcp_proxy_adapter/examples/README_EN.md +258 -0
- mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
- mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
- mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
- mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +43 -0
- mcp_proxy_adapter/examples/basic_framework/configs/https_no_protocol_middleware.json +36 -0
- mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +29 -0
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_protocol_middleware.json +34 -0
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_simple.json +35 -0
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
- mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
- mcp_proxy_adapter/examples/cert_config.json +9 -0
- mcp_proxy_adapter/examples/certs/admin.crt +32 -0
- mcp_proxy_adapter/examples/certs/admin.key +52 -0
- mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
- mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
- mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
- mcp_proxy_adapter/examples/certs/client.crt +32 -0
- mcp_proxy_adapter/examples/certs/client.key +52 -0
- mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
- mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
- mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
- mcp_proxy_adapter/examples/certs/client_user.key +52 -0
- mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
- mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
- mcp_proxy_adapter/examples/certs/readonly.key +52 -0
- mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
- mcp_proxy_adapter/examples/certs/server.crt +32 -0
- mcp_proxy_adapter/examples/certs/server.key +52 -0
- mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
- mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
- mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
- mcp_proxy_adapter/examples/certs/user.crt +32 -0
- mcp_proxy_adapter/examples/certs/user.key +52 -0
- mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
- mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
- mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
- mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
- mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
- mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
- mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
- mcp_proxy_adapter/examples/commands/__init__.py +1 -0
- mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
- mcp_proxy_adapter/examples/debug_request_state.py +144 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
- mcp_proxy_adapter/examples/demo_client.py +341 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
- mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
- mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
- mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
- mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
- mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
- mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
- mcp_proxy_adapter/examples/full_application/main.py +138 -0
- mcp_proxy_adapter/examples/full_application/roles.json +21 -0
- mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
- mcp_proxy_adapter/examples/generate_certificates.py +121 -0
- mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
- mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
- mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
- mcp_proxy_adapter/examples/roles.json +38 -0
- mcp_proxy_adapter/examples/run_example.py +81 -0
- mcp_proxy_adapter/examples/run_security_tests.py +326 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
- mcp_proxy_adapter/examples/security_test_client.py +743 -0
- mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
- mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
- mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
- mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
- mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
- mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
- mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
- mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
- mcp_proxy_adapter/examples/test_config_generator.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +344 -0
- mcp_proxy_adapter/examples/universal_client.py +628 -0
- mcp_proxy_adapter/main.py +21 -10
- mcp_proxy_adapter/utils/config_generator.py +727 -0
- mcp_proxy_adapter/version.py +5 -2
- mcp_proxy_adapter-6.1.1.dist-info/METADATA +205 -0
- mcp_proxy_adapter-6.1.1.dist-info/RECORD +197 -0
- mcp_proxy_adapter-6.1.1.dist-info/entry_points.txt +2 -0
- {mcp_proxy_adapter-6.0.0.dist-info โ mcp_proxy_adapter-6.1.1.dist-info}/licenses/LICENSE +2 -2
- mcp_proxy_adapter/api/middleware/auth.py +0 -146
- mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
- mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
- mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
- mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
- mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
- mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
- mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
- mcp_proxy_adapter/api/middleware/security.py +0 -376
- mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
- mcp_proxy_adapter/examples/__init__.py +0 -7
- mcp_proxy_adapter/examples/basic_server/README.md +0 -60
- mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
- mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
- mcp_proxy_adapter/examples/basic_server/config.json +0 -70
- mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
- mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
- mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
- mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
- mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
- mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
- mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
- mcp_proxy_adapter/examples/basic_server/server.py +0 -114
- mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
- mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
- mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
- mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
- mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
- mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
- mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
- mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
- mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
- mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
- mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
- mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
- mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
- mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
- mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
- mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
- mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
- mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
- mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
- mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
- mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
- mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
- mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
- mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
- mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
- mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
- mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
- mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
- mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
- mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
- mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
- mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
- mcp_proxy_adapter/examples/deployment/README.md +0 -49
- mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
- mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
- mcp_proxy_adapter/examples/deployment/config.json +0 -29
- mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
- mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
- mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
- mcp_proxy_adapter/examples/deployment/run.sh +0 -43
- mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
- mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
- mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
- mcp_proxy_adapter/schemas/base_schema.json +0 -114
- mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
- mcp_proxy_adapter/schemas/roles_schema.json +0 -162
- mcp_proxy_adapter/tests/__init__.py +0 -0
- mcp_proxy_adapter/tests/api/__init__.py +0 -3
- mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
- mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
- mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
- mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
- mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
- mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
- mcp_proxy_adapter/tests/commands/__init__.py +0 -3
- mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
- mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
- mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
- mcp_proxy_adapter/tests/conftest.py +0 -131
- mcp_proxy_adapter/tests/functional/__init__.py +0 -3
- mcp_proxy_adapter/tests/functional/test_api.py +0 -253
- mcp_proxy_adapter/tests/integration/__init__.py +0 -3
- mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
- mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
- mcp_proxy_adapter/tests/performance/__init__.py +0 -3
- mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
- mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
- mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
- mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
- mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
- mcp_proxy_adapter/tests/test_base_command.py +0 -123
- mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
- mcp_proxy_adapter/tests/test_command_registry.py +0 -281
- mcp_proxy_adapter/tests/test_config.py +0 -127
- mcp_proxy_adapter/tests/test_utils.py +0 -65
- mcp_proxy_adapter/tests/unit/__init__.py +0 -3
- mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
- mcp_proxy_adapter/tests/unit/test_config.py +0 -270
- mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
- mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
- {mcp_proxy_adapter-6.0.0.dist-info โ mcp_proxy_adapter-6.1.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.0.0.dist-info โ mcp_proxy_adapter-6.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"server": {
|
3
|
+
"host": "0.0.0.0",
|
4
|
+
"port": 8002,
|
5
|
+
"debug": false,
|
6
|
+
"workers": 1
|
7
|
+
},
|
8
|
+
|
9
|
+
"security": {
|
10
|
+
"framework": "none",
|
11
|
+
"enabled": false,
|
12
|
+
"debug": false,
|
13
|
+
"environment": "dev",
|
14
|
+
"version": "1.0.0"
|
15
|
+
},
|
16
|
+
|
17
|
+
"logging": {
|
18
|
+
"level": "INFO",
|
19
|
+
"console_output": true,
|
20
|
+
"file_output": false,
|
21
|
+
"file_path": "./logs/server.log",
|
22
|
+
"max_file_size": 10,
|
23
|
+
"backup_count": 5,
|
24
|
+
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
25
|
+
},
|
26
|
+
|
27
|
+
"commands": {
|
28
|
+
"auto_discovery": true,
|
29
|
+
"commands_directory": "./commands",
|
30
|
+
"builtin_commands": ["echo", "health", "config", "roletest", "proxy_registration"],
|
31
|
+
"custom_commands": [],
|
32
|
+
"command_timeout": 30
|
33
|
+
},
|
34
|
+
|
35
|
+
"protocol": {
|
36
|
+
"jsonrpc": {
|
37
|
+
"enabled": true,
|
38
|
+
"version": "2.0",
|
39
|
+
"endpoint": "/api/jsonrpc"
|
40
|
+
},
|
41
|
+
"rest": {
|
42
|
+
"enabled": true,
|
43
|
+
"endpoint": "/cmd"
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
{
|
2
|
+
"roles": {
|
3
|
+
"admin": {
|
4
|
+
"description": "Administrator with full access",
|
5
|
+
"permissions": ["*"],
|
6
|
+
"inherits": []
|
7
|
+
},
|
8
|
+
"user": {
|
9
|
+
"description": "Standard user with read/write access",
|
10
|
+
"permissions": ["read", "write"],
|
11
|
+
"inherits": ["readonly"]
|
12
|
+
},
|
13
|
+
"readonly": {
|
14
|
+
"description": "Read-only user",
|
15
|
+
"permissions": ["read"],
|
16
|
+
"inherits": []
|
17
|
+
},
|
18
|
+
"guest": {
|
19
|
+
"description": "Guest user with minimal access",
|
20
|
+
"permissions": ["read"],
|
21
|
+
"inherits": []
|
22
|
+
},
|
23
|
+
"proxy": {
|
24
|
+
"description": "Proxy registration and discovery",
|
25
|
+
"permissions": ["register", "heartbeat", "discover"],
|
26
|
+
"inherits": []
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"permissions": {
|
30
|
+
"read": "Read access to resources",
|
31
|
+
"write": "Write access to resources",
|
32
|
+
"delete": "Delete access to resources",
|
33
|
+
"manage": "Manage system settings",
|
34
|
+
"register": "Register proxy with registry",
|
35
|
+
"heartbeat": "Send heartbeat to registry",
|
36
|
+
"discover": "Discover other proxies"
|
37
|
+
}
|
38
|
+
}
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Test script for configuration generator utility.
|
4
|
+
|
5
|
+
This script tests the configuration generator to ensure it properly generates
|
6
|
+
configurations with the new protocols section and fixes for ProtocolMiddleware issues.
|
7
|
+
"""
|
8
|
+
|
9
|
+
import sys
|
10
|
+
import json
|
11
|
+
from pathlib import Path
|
12
|
+
|
13
|
+
# Add the project root to the path
|
14
|
+
project_root = Path(__file__).parent.parent.parent
|
15
|
+
sys.path.insert(0, str(project_root))
|
16
|
+
|
17
|
+
from mcp_proxy_adapter.utils.config_generator import ConfigGenerator
|
18
|
+
|
19
|
+
|
20
|
+
def test_config_generator():
|
21
|
+
"""Test the configuration generator with different types."""
|
22
|
+
generator = ConfigGenerator()
|
23
|
+
|
24
|
+
# Test configuration types
|
25
|
+
config_types = [
|
26
|
+
"basic_http",
|
27
|
+
"http_token",
|
28
|
+
"https",
|
29
|
+
"https_token",
|
30
|
+
"https_no_protocol_middleware",
|
31
|
+
"mtls",
|
32
|
+
"mtls_no_protocol_middleware"
|
33
|
+
]
|
34
|
+
|
35
|
+
print("Testing Configuration Generator")
|
36
|
+
print("=" * 50)
|
37
|
+
|
38
|
+
for config_type in config_types:
|
39
|
+
print(f"\nTesting {config_type} configuration:")
|
40
|
+
print("-" * 30)
|
41
|
+
|
42
|
+
try:
|
43
|
+
# Generate configuration
|
44
|
+
config = generator._get_config_by_type(config_type)
|
45
|
+
|
46
|
+
# Check if protocols section exists
|
47
|
+
if "protocols" in config:
|
48
|
+
protocols = config["protocols"]
|
49
|
+
print(f"โ
Protocols section found:")
|
50
|
+
print(f" - enabled: {protocols.get('enabled', 'NOT SET')}")
|
51
|
+
print(f" - allowed_protocols: {protocols.get('allowed_protocols', 'NOT SET')}")
|
52
|
+
print(f" - default_protocol: {protocols.get('default_protocol', 'NOT SET')}")
|
53
|
+
else:
|
54
|
+
print("โ Protocols section missing!")
|
55
|
+
|
56
|
+
# Check SSL configuration
|
57
|
+
ssl_enabled = config.get("ssl", {}).get("enabled", False)
|
58
|
+
security_ssl_enabled = config.get("security", {}).get("ssl", {}).get("enabled", False)
|
59
|
+
print(f" - legacy ssl.enabled: {ssl_enabled}")
|
60
|
+
print(f" - security.ssl.enabled: {security_ssl_enabled}")
|
61
|
+
|
62
|
+
# Check if configuration is valid for its type
|
63
|
+
if config_type == "https_no_protocol_middleware" or config_type == "mtls_no_protocol_middleware":
|
64
|
+
if protocols.get("enabled") == False:
|
65
|
+
print("โ
ProtocolMiddleware correctly disabled")
|
66
|
+
else:
|
67
|
+
print("โ ProtocolMiddleware should be disabled but is enabled")
|
68
|
+
else:
|
69
|
+
if protocols.get("enabled") == True:
|
70
|
+
print("โ
ProtocolMiddleware correctly enabled")
|
71
|
+
else:
|
72
|
+
print("โ ProtocolMiddleware should be enabled but is disabled")
|
73
|
+
|
74
|
+
# Save configuration to file for inspection
|
75
|
+
output_file = f"test_config_{config_type}.json"
|
76
|
+
with open(output_file, 'w') as f:
|
77
|
+
json.dump(config, f, indent=2)
|
78
|
+
print(f" - Configuration saved to {output_file}")
|
79
|
+
|
80
|
+
except Exception as e:
|
81
|
+
print(f"โ Error generating {config_type} configuration: {e}")
|
82
|
+
|
83
|
+
print("\n" + "=" * 50)
|
84
|
+
print("Configuration generator test completed!")
|
85
|
+
|
86
|
+
|
87
|
+
def test_config_with_comments():
|
88
|
+
"""Test configuration generation with comments."""
|
89
|
+
generator = ConfigGenerator()
|
90
|
+
|
91
|
+
print("\nTesting configuration with comments:")
|
92
|
+
print("-" * 40)
|
93
|
+
|
94
|
+
try:
|
95
|
+
# Generate HTTPS configuration with comments
|
96
|
+
commented_config = generator.generate_config_with_comments("https")
|
97
|
+
print("โ
HTTPS configuration with comments generated successfully")
|
98
|
+
|
99
|
+
# Save to file
|
100
|
+
with open("test_https_with_comments.json", 'w') as f:
|
101
|
+
f.write(commented_config)
|
102
|
+
print(" - Configuration saved to test_https_with_comments.json")
|
103
|
+
|
104
|
+
except Exception as e:
|
105
|
+
print(f"โ Error generating configuration with comments: {e}")
|
106
|
+
|
107
|
+
|
108
|
+
if __name__ == "__main__":
|
109
|
+
test_config_generator()
|
110
|
+
test_config_with_comments()
|
@@ -0,0 +1,344 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Test Examples Script
|
4
|
+
|
5
|
+
This script tests all examples with different configurations.
|
6
|
+
|
7
|
+
Author: Vasiliy Zdanovskiy
|
8
|
+
email: vasilyvz@gmail.com
|
9
|
+
"""
|
10
|
+
|
11
|
+
import json
|
12
|
+
import os
|
13
|
+
import subprocess
|
14
|
+
import time
|
15
|
+
import requests
|
16
|
+
from pathlib import Path
|
17
|
+
from typing import Dict, Any, List
|
18
|
+
|
19
|
+
# Configuration for testing
|
20
|
+
CONFIGS = {
|
21
|
+
"basic_framework": {
|
22
|
+
"http_simple": {"port": 8000, "ssl": False, "auth": False},
|
23
|
+
"https_simple": {"port": 8443, "ssl": True, "auth": False},
|
24
|
+
"http_auth": {"port": 8001, "ssl": False, "auth": True},
|
25
|
+
"https_auth": {"port": 8444, "ssl": True, "auth": True},
|
26
|
+
"mtls_no_roles": {"port": 9443, "ssl": True, "auth": True, "mtls": True},
|
27
|
+
"mtls_with_roles": {"port": 9444, "ssl": True, "auth": True, "mtls": True}
|
28
|
+
},
|
29
|
+
"full_application": {
|
30
|
+
"http_simple": {"port": 9000, "ssl": False, "auth": False},
|
31
|
+
"https_simple": {"port": 9445, "ssl": True, "auth": False},
|
32
|
+
"http_auth": {"port": 9001, "ssl": False, "auth": True},
|
33
|
+
"https_auth": {"port": 9446, "ssl": True, "auth": True},
|
34
|
+
"mtls_no_roles": {"port": 9447, "ssl": True, "auth": True, "mtls": True},
|
35
|
+
"mtls_with_roles": {"port": 9448, "ssl": True, "auth": True, "mtls": True}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
API_KEYS = {
|
40
|
+
"admin": "admin-secret-key-123",
|
41
|
+
"user": "user-secret-key-456"
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
class ExampleTester:
|
46
|
+
"""Test examples with different configurations."""
|
47
|
+
|
48
|
+
def __init__(self):
|
49
|
+
self.examples_dir = Path(__file__).parent
|
50
|
+
self.results = {}
|
51
|
+
self.processes = []
|
52
|
+
|
53
|
+
def generate_certificates(self):
|
54
|
+
"""Generate certificates for testing."""
|
55
|
+
print("๐ Generating certificates...")
|
56
|
+
|
57
|
+
cert_script = self.examples_dir.parent / "generate_certificates.py"
|
58
|
+
if cert_script.exists():
|
59
|
+
result = subprocess.run([sys.executable, str(cert_script)],
|
60
|
+
capture_output=True, text=True)
|
61
|
+
if result.returncode == 0:
|
62
|
+
print("โ
Certificates generated successfully")
|
63
|
+
return True
|
64
|
+
else:
|
65
|
+
print(f"โ Certificate generation failed: {result.stderr}")
|
66
|
+
return False
|
67
|
+
else:
|
68
|
+
print("โ ๏ธ Certificate generation script not found, using existing certificates")
|
69
|
+
return True
|
70
|
+
|
71
|
+
def start_server(self, example_type: str, config_name: str) -> subprocess.Popen:
|
72
|
+
"""Start a server with specific configuration."""
|
73
|
+
config_path = self.examples_dir / example_type / "configs" / f"{config_name}.json"
|
74
|
+
main_script = self.examples_dir / example_type / "main.py"
|
75
|
+
|
76
|
+
if not config_path.exists():
|
77
|
+
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
78
|
+
|
79
|
+
if not main_script.exists():
|
80
|
+
raise FileNotFoundError(f"Main script not found: {main_script}")
|
81
|
+
|
82
|
+
cmd = [
|
83
|
+
sys.executable, str(main_script),
|
84
|
+
"--config", str(config_path)
|
85
|
+
]
|
86
|
+
|
87
|
+
print(f"๐ Starting {example_type} server with {config_name} config...")
|
88
|
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
89
|
+
|
90
|
+
# Wait for server to start
|
91
|
+
time.sleep(5)
|
92
|
+
|
93
|
+
return process
|
94
|
+
|
95
|
+
def test_health_endpoint(self, port: int, ssl: bool = False, auth: bool = False,
|
96
|
+
api_key: str = None) -> Dict[str, Any]:
|
97
|
+
"""Test health endpoint."""
|
98
|
+
protocol = "https" if ssl else "http"
|
99
|
+
url = f"{protocol}://localhost:{port}/health"
|
100
|
+
|
101
|
+
headers = {}
|
102
|
+
if auth and api_key:
|
103
|
+
headers["X-API-Key"] = api_key
|
104
|
+
|
105
|
+
try:
|
106
|
+
response = requests.get(url, headers=headers, verify=False, timeout=10)
|
107
|
+
return {
|
108
|
+
"success": True,
|
109
|
+
"status_code": response.status_code,
|
110
|
+
"response": response.json() if response.headers.get('content-type', '').startswith('application/json') else response.text
|
111
|
+
}
|
112
|
+
except Exception as e:
|
113
|
+
return {
|
114
|
+
"success": False,
|
115
|
+
"error": str(e)
|
116
|
+
}
|
117
|
+
|
118
|
+
def test_echo_command(self, port: int, ssl: bool = False, auth: bool = False,
|
119
|
+
api_key: str = None) -> Dict[str, Any]:
|
120
|
+
"""Test echo command."""
|
121
|
+
protocol = "https" if ssl else "http"
|
122
|
+
url = f"{protocol}://localhost:{port}/cmd"
|
123
|
+
|
124
|
+
headers = {"Content-Type": "application/json"}
|
125
|
+
if auth and api_key:
|
126
|
+
headers["X-API-Key"] = api_key
|
127
|
+
|
128
|
+
data = {
|
129
|
+
"jsonrpc": "2.0",
|
130
|
+
"method": "echo",
|
131
|
+
"params": {"message": "Hello from test!"},
|
132
|
+
"id": 1
|
133
|
+
}
|
134
|
+
|
135
|
+
try:
|
136
|
+
response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
|
137
|
+
return {
|
138
|
+
"success": True,
|
139
|
+
"status_code": response.status_code,
|
140
|
+
"response": response.json()
|
141
|
+
}
|
142
|
+
except Exception as e:
|
143
|
+
return {
|
144
|
+
"success": False,
|
145
|
+
"error": str(e)
|
146
|
+
}
|
147
|
+
|
148
|
+
def test_full_application_commands(self, port: int, ssl: bool = False, auth: bool = False,
|
149
|
+
api_key: str = None) -> Dict[str, Any]:
|
150
|
+
"""Test full application specific commands."""
|
151
|
+
protocol = "https" if ssl else "http"
|
152
|
+
url = f"{protocol}://localhost:{port}/cmd"
|
153
|
+
|
154
|
+
headers = {"Content-Type": "application/json"}
|
155
|
+
if auth and api_key:
|
156
|
+
headers["X-API-Key"] = api_key
|
157
|
+
|
158
|
+
results = {}
|
159
|
+
|
160
|
+
# Test custom echo command
|
161
|
+
data = {
|
162
|
+
"jsonrpc": "2.0",
|
163
|
+
"method": "custom_echo",
|
164
|
+
"params": {"message": "Custom echo test", "repeat": 3},
|
165
|
+
"id": 1
|
166
|
+
}
|
167
|
+
|
168
|
+
try:
|
169
|
+
response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
|
170
|
+
results["custom_echo"] = {
|
171
|
+
"success": True,
|
172
|
+
"status_code": response.status_code,
|
173
|
+
"response": response.json()
|
174
|
+
}
|
175
|
+
except Exception as e:
|
176
|
+
results["custom_echo"] = {
|
177
|
+
"success": False,
|
178
|
+
"error": str(e)
|
179
|
+
}
|
180
|
+
|
181
|
+
# Test dynamic calculator command
|
182
|
+
data = {
|
183
|
+
"jsonrpc": "2.0",
|
184
|
+
"method": "dynamic_calculator",
|
185
|
+
"params": {"operation": "add", "a": 10, "b": 5},
|
186
|
+
"id": 2
|
187
|
+
}
|
188
|
+
|
189
|
+
try:
|
190
|
+
response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
|
191
|
+
results["dynamic_calculator"] = {
|
192
|
+
"success": True,
|
193
|
+
"status_code": response.status_code,
|
194
|
+
"response": response.json()
|
195
|
+
}
|
196
|
+
except Exception as e:
|
197
|
+
results["dynamic_calculator"] = {
|
198
|
+
"success": False,
|
199
|
+
"error": str(e)
|
200
|
+
}
|
201
|
+
|
202
|
+
return results
|
203
|
+
|
204
|
+
def run_tests(self):
|
205
|
+
"""Run all tests."""
|
206
|
+
print("๐งช Starting Example Tests")
|
207
|
+
print("=" * 60)
|
208
|
+
|
209
|
+
# Generate certificates first
|
210
|
+
if not self.generate_certificates():
|
211
|
+
print("โ Certificate generation failed, skipping tests")
|
212
|
+
return
|
213
|
+
|
214
|
+
for example_type, configs in CONFIGS.items():
|
215
|
+
print(f"\n๐ Testing {example_type.upper()}")
|
216
|
+
print("-" * 40)
|
217
|
+
|
218
|
+
for config_name, config_info in configs.items():
|
219
|
+
print(f"\n๐ง Testing {config_name} configuration...")
|
220
|
+
|
221
|
+
try:
|
222
|
+
# Start server
|
223
|
+
process = self.start_server(example_type, config_name)
|
224
|
+
self.processes.append(process)
|
225
|
+
|
226
|
+
port = config_info["port"]
|
227
|
+
ssl = config_info.get("ssl", False)
|
228
|
+
auth = config_info.get("auth", False)
|
229
|
+
|
230
|
+
# Test health endpoint
|
231
|
+
print(f" ๐ Testing health endpoint...")
|
232
|
+
health_result = self.test_health_endpoint(port, ssl, auth)
|
233
|
+
print(f" Health: {'โ
' if health_result['success'] else 'โ'}")
|
234
|
+
|
235
|
+
# Test echo command
|
236
|
+
print(f" ๐ Testing echo command...")
|
237
|
+
if auth:
|
238
|
+
# Test with admin key
|
239
|
+
echo_result = self.test_echo_command(port, ssl, auth, API_KEYS["admin"])
|
240
|
+
else:
|
241
|
+
echo_result = self.test_echo_command(port, ssl, auth)
|
242
|
+
print(f" Echo: {'โ
' if echo_result['success'] else 'โ'}")
|
243
|
+
|
244
|
+
# Test full application specific commands
|
245
|
+
if example_type == "full_application":
|
246
|
+
print(f" ๐ง Testing full application commands...")
|
247
|
+
app_results = self.test_full_application_commands(port, ssl, auth,
|
248
|
+
API_KEYS["admin"] if auth else None)
|
249
|
+
for cmd_name, result in app_results.items():
|
250
|
+
print(f" {cmd_name}: {'โ
' if result['success'] else 'โ'}")
|
251
|
+
|
252
|
+
# Store results
|
253
|
+
self.results[f"{example_type}_{config_name}"] = {
|
254
|
+
"health": health_result,
|
255
|
+
"echo": echo_result,
|
256
|
+
"config_info": config_info
|
257
|
+
}
|
258
|
+
|
259
|
+
if example_type == "full_application":
|
260
|
+
self.results[f"{example_type}_{config_name}"]["app_commands"] = app_results
|
261
|
+
|
262
|
+
except Exception as e:
|
263
|
+
print(f" โ Error testing {config_name}: {e}")
|
264
|
+
self.results[f"{example_type}_{config_name}"] = {
|
265
|
+
"error": str(e),
|
266
|
+
"config_info": config_info
|
267
|
+
}
|
268
|
+
|
269
|
+
finally:
|
270
|
+
# Stop server
|
271
|
+
if process:
|
272
|
+
process.terminate()
|
273
|
+
process.wait()
|
274
|
+
time.sleep(2)
|
275
|
+
|
276
|
+
self.print_results()
|
277
|
+
|
278
|
+
def print_results(self):
|
279
|
+
"""Print test results."""
|
280
|
+
print("\n๐ Test Results Summary")
|
281
|
+
print("=" * 60)
|
282
|
+
|
283
|
+
total_tests = len(self.results)
|
284
|
+
successful_tests = 0
|
285
|
+
|
286
|
+
for test_name, result in self.results.items():
|
287
|
+
print(f"\n๐ {test_name}")
|
288
|
+
|
289
|
+
if "error" in result:
|
290
|
+
print(f" โ Error: {result['error']}")
|
291
|
+
continue
|
292
|
+
|
293
|
+
# Check health test
|
294
|
+
health_success = result.get("health", {}).get("success", False)
|
295
|
+
print(f" Health: {'โ
' if health_success else 'โ'}")
|
296
|
+
|
297
|
+
# Check echo test
|
298
|
+
echo_success = result.get("echo", {}).get("success", False)
|
299
|
+
print(f" Echo: {'โ
' if echo_success else 'โ'}")
|
300
|
+
|
301
|
+
# Check app commands for full application
|
302
|
+
if "app_commands" in result:
|
303
|
+
app_success = all(cmd_result.get("success", False)
|
304
|
+
for cmd_result in result["app_commands"].values())
|
305
|
+
print(f" App Commands: {'โ
' if app_success else 'โ'}")
|
306
|
+
|
307
|
+
# Overall test success
|
308
|
+
test_success = health_success and echo_success
|
309
|
+
if test_success:
|
310
|
+
successful_tests += 1
|
311
|
+
|
312
|
+
print(f"\n๐ฏ Overall Results: {successful_tests}/{total_tests} tests passed")
|
313
|
+
|
314
|
+
if successful_tests == total_tests:
|
315
|
+
print("๐ All tests passed!")
|
316
|
+
else:
|
317
|
+
print("โ ๏ธ Some tests failed. Check the details above.")
|
318
|
+
|
319
|
+
def cleanup(self):
|
320
|
+
"""Cleanup processes."""
|
321
|
+
for process in self.processes:
|
322
|
+
if process.poll() is None:
|
323
|
+
process.terminate()
|
324
|
+
process.wait()
|
325
|
+
|
326
|
+
|
327
|
+
def main():
|
328
|
+
"""Main function."""
|
329
|
+
import sys
|
330
|
+
|
331
|
+
tester = ExampleTester()
|
332
|
+
|
333
|
+
try:
|
334
|
+
tester.run_tests()
|
335
|
+
except KeyboardInterrupt:
|
336
|
+
print("\n๐ Tests interrupted by user")
|
337
|
+
except Exception as e:
|
338
|
+
print(f"\nโ Test execution failed: {e}")
|
339
|
+
finally:
|
340
|
+
tester.cleanup()
|
341
|
+
|
342
|
+
|
343
|
+
if __name__ == "__main__":
|
344
|
+
main()
|