mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mcp-proxy-adapter might be problematic. Click here for more details.

Files changed (269) hide show
  1. mcp_proxy_adapter/__init__.py +47 -0
  2. mcp_proxy_adapter/__main__.py +13 -0
  3. mcp_proxy_adapter/api/__init__.py +0 -0
  4. mcp_proxy_adapter/api/app.py +66 -0
  5. mcp_proxy_adapter/api/core/__init__.py +18 -0
  6. mcp_proxy_adapter/api/core/app_factory.py +400 -0
  7. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  8. mcp_proxy_adapter/api/core/registration_context.py +356 -0
  9. mcp_proxy_adapter/api/core/registration_manager.py +307 -0
  10. mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
  11. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  12. mcp_proxy_adapter/api/handlers.py +181 -0
  13. mcp_proxy_adapter/api/middleware/__init__.py +21 -0
  14. mcp_proxy_adapter/api/middleware/base.py +54 -0
  15. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
  16. mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
  17. mcp_proxy_adapter/api/middleware/factory.py +147 -0
  18. mcp_proxy_adapter/api/middleware/logging.py +31 -0
  19. mcp_proxy_adapter/api/middleware/performance.py +51 -0
  20. mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
  21. mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
  22. mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
  23. mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
  24. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  25. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  26. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  27. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  28. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  29. mcp_proxy_adapter/api/schemas.py +270 -0
  30. mcp_proxy_adapter/api/tool_integration.py +131 -0
  31. mcp_proxy_adapter/api/tools.py +163 -0
  32. mcp_proxy_adapter/cli/__init__.py +12 -0
  33. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  34. mcp_proxy_adapter/cli/commands/client.py +100 -0
  35. mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
  36. mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
  37. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  38. mcp_proxy_adapter/cli/commands/server.py +174 -0
  39. mcp_proxy_adapter/cli/commands/sets.py +132 -0
  40. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  41. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  42. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  43. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  44. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  45. mcp_proxy_adapter/cli/main.py +63 -0
  46. mcp_proxy_adapter/cli/parser.py +338 -0
  47. mcp_proxy_adapter/cli/validators.py +231 -0
  48. mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
  49. mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
  50. mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
  51. mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
  52. mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
  53. mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
  54. mcp_proxy_adapter/client/proxy.py +123 -0
  55. mcp_proxy_adapter/commands/__init__.py +66 -0
  56. mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
  57. mcp_proxy_adapter/commands/base.py +389 -0
  58. mcp_proxy_adapter/commands/builtin_commands.py +30 -0
  59. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  60. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  61. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  62. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  63. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  64. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  65. mcp_proxy_adapter/commands/catalog_manager.py +97 -0
  66. mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
  67. mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
  68. mcp_proxy_adapter/commands/command_registry.py +298 -0
  69. mcp_proxy_adapter/commands/config_command.py +102 -0
  70. mcp_proxy_adapter/commands/dependency_container.py +40 -0
  71. mcp_proxy_adapter/commands/dependency_manager.py +143 -0
  72. mcp_proxy_adapter/commands/echo_command.py +48 -0
  73. mcp_proxy_adapter/commands/health_command.py +142 -0
  74. mcp_proxy_adapter/commands/help_command.py +175 -0
  75. mcp_proxy_adapter/commands/hooks.py +172 -0
  76. mcp_proxy_adapter/commands/key_management_command.py +484 -0
  77. mcp_proxy_adapter/commands/load_command.py +123 -0
  78. mcp_proxy_adapter/commands/plugins_command.py +246 -0
  79. mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
  80. mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
  81. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  82. mcp_proxy_adapter/commands/registration_status_command.py +76 -0
  83. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  84. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  85. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  86. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  87. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  88. mcp_proxy_adapter/commands/reload_command.py +136 -0
  89. mcp_proxy_adapter/commands/result.py +157 -0
  90. mcp_proxy_adapter/commands/role_test_command.py +99 -0
  91. mcp_proxy_adapter/commands/roles_management_command.py +502 -0
  92. mcp_proxy_adapter/commands/security_command.py +472 -0
  93. mcp_proxy_adapter/commands/settings_command.py +113 -0
  94. mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
  95. mcp_proxy_adapter/commands/token_management_command.py +500 -0
  96. mcp_proxy_adapter/commands/transport_management_command.py +129 -0
  97. mcp_proxy_adapter/commands/unload_command.py +92 -0
  98. mcp_proxy_adapter/config.py +32 -0
  99. mcp_proxy_adapter/core/__init__.py +8 -0
  100. mcp_proxy_adapter/core/app_factory.py +560 -0
  101. mcp_proxy_adapter/core/app_runner.py +318 -0
  102. mcp_proxy_adapter/core/auth_validator.py +508 -0
  103. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  104. mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
  105. mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
  106. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  107. mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
  108. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
  109. mcp_proxy_adapter/core/certificate_utils.py +249 -0
  110. mcp_proxy_adapter/core/client.py +608 -0
  111. mcp_proxy_adapter/core/client_manager.py +271 -0
  112. mcp_proxy_adapter/core/client_security.py +411 -0
  113. mcp_proxy_adapter/core/config/__init__.py +18 -0
  114. mcp_proxy_adapter/core/config/config.py +237 -0
  115. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  116. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  117. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  118. mcp_proxy_adapter/core/config/simple_config.py +204 -0
  119. mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
  120. mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
  121. mcp_proxy_adapter/core/config_converter.py +252 -0
  122. mcp_proxy_adapter/core/config_validator.py +211 -0
  123. mcp_proxy_adapter/core/crl_utils.py +362 -0
  124. mcp_proxy_adapter/core/errors.py +276 -0
  125. mcp_proxy_adapter/core/job_manager.py +54 -0
  126. mcp_proxy_adapter/core/logging.py +250 -0
  127. mcp_proxy_adapter/core/mtls_asgi.py +140 -0
  128. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  129. mcp_proxy_adapter/core/mtls_proxy.py +229 -0
  130. mcp_proxy_adapter/core/mtls_server.py +154 -0
  131. mcp_proxy_adapter/core/protocol_manager.py +232 -0
  132. mcp_proxy_adapter/core/proxy/__init__.py +19 -0
  133. mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
  134. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
  135. mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
  136. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  137. mcp_proxy_adapter/core/proxy_client.py +184 -0
  138. mcp_proxy_adapter/core/proxy_registration.py +80 -0
  139. mcp_proxy_adapter/core/role_utils.py +103 -0
  140. mcp_proxy_adapter/core/security_adapter.py +343 -0
  141. mcp_proxy_adapter/core/security_factory.py +96 -0
  142. mcp_proxy_adapter/core/security_integration.py +342 -0
  143. mcp_proxy_adapter/core/server_adapter.py +251 -0
  144. mcp_proxy_adapter/core/server_engine.py +217 -0
  145. mcp_proxy_adapter/core/settings.py +260 -0
  146. mcp_proxy_adapter/core/signal_handler.py +107 -0
  147. mcp_proxy_adapter/core/ssl_utils.py +161 -0
  148. mcp_proxy_adapter/core/transport_manager.py +153 -0
  149. mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
  150. mcp_proxy_adapter/core/utils.py +101 -0
  151. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  152. mcp_proxy_adapter/core/validation/config_validator.py +219 -0
  153. mcp_proxy_adapter/core/validation/file_validator.py +131 -0
  154. mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
  155. mcp_proxy_adapter/core/validation/security_validator.py +140 -0
  156. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  157. mcp_proxy_adapter/custom_openapi.py +58 -0
  158. mcp_proxy_adapter/examples/__init__.py +16 -0
  159. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  160. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  161. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  162. mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
  163. mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
  164. mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
  165. mcp_proxy_adapter/examples/check_config.py +413 -0
  166. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  167. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  168. mcp_proxy_adapter/examples/config_builder.py +234 -0
  169. mcp_proxy_adapter/examples/config_cli.py +282 -0
  170. mcp_proxy_adapter/examples/create_test_configs.py +174 -0
  171. mcp_proxy_adapter/examples/debug_request_state.py +130 -0
  172. mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
  173. mcp_proxy_adapter/examples/demo_client.py +287 -0
  174. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  175. mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
  176. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
  177. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
  178. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
  179. mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
  180. mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
  181. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
  182. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
  183. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
  184. mcp_proxy_adapter/examples/full_application/main.py +311 -0
  185. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
  186. mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
  187. mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
  188. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
  189. mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
  190. mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
  191. mcp_proxy_adapter/examples/generate_config.py +502 -0
  192. mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
  193. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  194. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  195. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  196. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  197. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  198. mcp_proxy_adapter/examples/required_certificates.py +208 -0
  199. mcp_proxy_adapter/examples/run_example.py +77 -0
  200. mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
  201. mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
  202. mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
  203. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  204. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  205. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  206. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  207. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  208. mcp_proxy_adapter/examples/security_test_client.py +72 -0
  209. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  210. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  211. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  212. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  213. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  214. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  215. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  216. mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
  217. mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
  218. mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
  219. mcp_proxy_adapter/examples/test_config.py +205 -0
  220. mcp_proxy_adapter/examples/test_config_builder.py +110 -0
  221. mcp_proxy_adapter/examples/test_examples.py +308 -0
  222. mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
  223. mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
  224. mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
  225. mcp_proxy_adapter/examples/universal_client.py +674 -0
  226. mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
  227. mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
  228. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
  229. mcp_proxy_adapter/integrations/__init__.py +25 -0
  230. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  231. mcp_proxy_adapter/main.py +311 -0
  232. mcp_proxy_adapter/openapi.py +375 -0
  233. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  234. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  235. mcp_proxy_adapter/schemas/roles.json +37 -0
  236. mcp_proxy_adapter/schemas/roles_schema.json +162 -0
  237. mcp_proxy_adapter/version.py +5 -0
  238. mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
  239. mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
  240. {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
  241. mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
  242. mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
  243. adapters/__init__.py +0 -16
  244. analyzers/__init__.py +0 -14
  245. analyzers/docstring_analyzer.py +0 -199
  246. analyzers/type_analyzer.py +0 -151
  247. cli/__init__.py +0 -12
  248. cli/__main__.py +0 -79
  249. cli/command_runner.py +0 -233
  250. dispatchers/__init__.py +0 -14
  251. dispatchers/base_dispatcher.py +0 -85
  252. dispatchers/json_rpc_dispatcher.py +0 -198
  253. generators/__init__.py +0 -14
  254. generators/endpoint_generator.py +0 -172
  255. generators/openapi_generator.py +0 -254
  256. generators/rest_api_generator.py +0 -207
  257. mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
  258. mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
  259. mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
  260. mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
  261. openapi_schema/__init__.py +0 -38
  262. openapi_schema/command_registry.py +0 -312
  263. openapi_schema/rest_schema.py +0 -510
  264. openapi_schema/rpc_generator.py +0 -307
  265. openapi_schema/rpc_schema.py +0 -416
  266. validators/__init__.py +0 -14
  267. validators/base_validator.py +0 -23
  268. validators/docstring_validator.py +0 -75
  269. validators/metadata_validator.py +0 -76
@@ -0,0 +1,159 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Main security test client for comprehensive testing.
6
+ """
7
+
8
+ import time
9
+ from pathlib import Path
10
+
11
+ from aiohttp import ClientSession, ClientTimeout, TCPConnector
12
+
13
+ from .test_result import TestResult
14
+ from .ssl_context_manager import SSLContextManager
15
+ from .auth_manager import AuthManager
16
+
17
+
18
+ class SecurityTestClient:
19
+ """Security test client for comprehensive testing."""
20
+
21
+ def __init__(self, base_url: str = "http://localhost:8000"):
22
+ """
23
+ Initialize security test client.
24
+
25
+ Args:
26
+ base_url: Base URL for the server
27
+ """
28
+ self.base_url = base_url
29
+ self.session: Optional[ClientSession] = None
30
+ self.test_results: List[TestResult] = []
31
+
32
+ # Initialize managers
33
+ project_root = Path(__file__).parent.parent.parent.parent
34
+ self.ssl_manager = SSLContextManager(project_root)
35
+ self.auth_manager = AuthManager()
36
+
37
+ async def __aenter__(self):
38
+ """Async context manager entry."""
39
+ timeout = ClientTimeout(total=30)
40
+ # Create SSL context only for HTTPS URLs
41
+ if self.base_url.startswith('https://'):
42
+ # Check if this is mTLS (ports 20006, 20007, 20008 are mTLS test ports)
43
+ if any(port in self.base_url for port in ['20006', '20007', '20008']):
44
+ # Use mTLS context with client certificates
45
+ ssl_context = self.ssl_manager.create_ssl_context_for_mtls()
46
+ else:
47
+ # Use regular HTTPS context
48
+ ssl_context = self.ssl_manager.create_ssl_context()
49
+ connector = TCPConnector(ssl=ssl_context)
50
+ else:
51
+ # For HTTP URLs, use default connector without SSL
52
+ connector = TCPConnector()
53
+
54
+ # Create session
55
+ self.session = ClientSession(timeout=timeout, connector=connector)
56
+ return self
57
+
58
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
59
+ """Async context manager exit."""
60
+ if self.session:
61
+ await self.session.close()
62
+
63
+ async def test_health_check(
64
+ self, server_url: str, auth_type: str = "none", **kwargs
65
+ ) -> TestResult:
66
+ """Test health check endpoint."""
67
+ start_time = time.time()
68
+ test_name = f"Health Check ({auth_type})"
69
+ try:
70
+ headers = self.auth_manager.create_auth_headers(auth_type, **kwargs)
71
+ async with self.session.get(
72
+ f"{server_url}/health", headers=headers
73
+ ) as response:
74
+ duration = time.time() - start_time
75
+ if response.status == 200:
76
+ data = await response.json()
77
+ return TestResult(
78
+ test_name=test_name,
79
+ server_url=server_url,
80
+ auth_type=auth_type,
81
+ success=True,
82
+ status_code=response.status,
83
+ response_data=data,
84
+ duration=duration
85
+ )
86
+ else:
87
+ error_text = await response.text()
88
+ return TestResult(
89
+ test_name=test_name,
90
+ server_url=server_url,
91
+ auth_type=auth_type,
92
+ success=False,
93
+ status_code=response.status,
94
+ error_message=f"HTTP {response.status}: {error_text}",
95
+ duration=duration
96
+ )
97
+ except Exception as e:
98
+ duration = time.time() - start_time
99
+ return TestResult(
100
+ test_name=test_name,
101
+ server_url=server_url,
102
+ auth_type=auth_type,
103
+ success=False,
104
+ error_message=str(e),
105
+ duration=duration
106
+ )
107
+
108
+ async def test_echo_command(
109
+ self, server_url: str, auth_type: str = "none", **kwargs
110
+ ) -> TestResult:
111
+ """Test echo command endpoint."""
112
+ start_time = time.time()
113
+ test_name = f"Echo Command ({auth_type})"
114
+ try:
115
+ headers = self.auth_manager.create_auth_headers(auth_type, **kwargs)
116
+ payload = {
117
+ "jsonrpc": "2.0",
118
+ "method": "echo",
119
+ "params": {"message": "Hello from security test client"},
120
+ "id": 1
121
+ }
122
+ async with self.session.post(
123
+ f"{server_url}/api/jsonrpc", json=payload, headers=headers
124
+ ) as response:
125
+ duration = time.time() - start_time
126
+ if response.status == 200:
127
+ data = await response.json()
128
+ return TestResult(
129
+ test_name=test_name,
130
+ server_url=server_url,
131
+ auth_type=auth_type,
132
+ success=True,
133
+ status_code=response.status,
134
+ response_data=data,
135
+ duration=duration
136
+ )
137
+ else:
138
+ error_text = await response.text()
139
+ return TestResult(
140
+ test_name=test_name,
141
+ server_url=server_url,
142
+ auth_type=auth_type,
143
+ success=False,
144
+ status_code=response.status,
145
+ error_message=f"HTTP {response.status}: {error_text}",
146
+ duration=duration
147
+ )
148
+ except Exception as e:
149
+ duration = time.time() - start_time
150
+ return TestResult(
151
+ test_name=test_name,
152
+ server_url=server_url,
153
+ auth_type=auth_type,
154
+ success=False,
155
+ error_message=str(e),
156
+ duration=duration
157
+ )
158
+
159
+
@@ -0,0 +1,22 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Test result data class for security testing.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from typing import Dict, Optional
10
+
11
+
12
+ @dataclass
13
+ class TestResult:
14
+ """Test result data class."""
15
+ test_name: str
16
+ server_url: str
17
+ auth_type: str
18
+ success: bool
19
+ status_code: Optional[int] = None
20
+ response_data: Optional[Dict] = None
21
+ error_message: Optional[str] = None
22
+ duration: float = 0.0
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Security Test Client for MCP Proxy Adapter
4
+ This client tests various security configurations including:
5
+ - Basic HTTP
6
+ - HTTP + Token authentication
7
+ - HTTPS
8
+ - HTTPS + Token authentication
9
+ - mTLS with certificate authentication
10
+
11
+ Author: Vasiliy Zdanovskiy
12
+ email: vasilyvz@gmail.com
13
+ """
14
+ import asyncio
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ # Add project root to path for imports
19
+ current_dir = Path(__file__).parent
20
+ parent_dir = current_dir.parent
21
+ if parent_dir.exists():
22
+ sys.path.insert(0, str(parent_dir))
23
+ sys.path.insert(0, str(current_dir))
24
+
25
+ # Import mcp_security_framework components
26
+ try:
27
+ _MCP_SECURITY_AVAILABLE = True
28
+ print("✅ mcp_security_framework available")
29
+ except ImportError as e:
30
+ print(f"❌ CRITICAL ERROR: mcp_security_framework is required but not available!")
31
+ print(f"❌ Import error: {e}")
32
+ print("❌ Please install mcp_security_framework: pip install mcp_security_framework")
33
+ raise ImportError("mcp_security_framework is required for security tests") from e
34
+
35
+ # Import cryptography components
36
+ try:
37
+ _CRYPTOGRAPHY_AVAILABLE = True
38
+ print("✅ cryptography available")
39
+ except ImportError:
40
+ _CRYPTOGRAPHY_AVAILABLE = False
41
+ print("⚠️ cryptography not available, SSL validation will be limited")
42
+
43
+ # Import security test components
44
+ from .security_test import SecurityTestClient
45
+
46
+
47
+ async def main():
48
+ """Main function to run security tests."""
49
+ print("🚀 Starting MCP Proxy Adapter Security Tests")
50
+ print("=" * 50)
51
+
52
+ # Define test servers
53
+ test_servers = [
54
+ "http://localhost:8080", # HTTP Basic
55
+ "http://localhost:8080", # HTTP + Token
56
+ "https://localhost:8443", # HTTPS Basic
57
+ "https://localhost:8443", # HTTPS + Token
58
+ "https://localhost:20006", # mTLS Basic
59
+ "https://localhost:20007", # mTLS + Token
60
+ "https://localhost:20008", # mTLS + Roles
61
+ ]
62
+
63
+ # Run security tests
64
+ async with SecurityTestClient() as client:
65
+ results = await client.run_security_tests(test_servers)
66
+ client.print_summary()
67
+
68
+ print("\\n🎉 Security tests completed!")
69
+
70
+
71
+ if __name__ == "__main__":
72
+ asyncio.run(main())
@@ -0,0 +1,24 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Test environment setup package for MCP Proxy Adapter.
6
+ """
7
+
8
+ from .config_validator import ConfigurationValidator
9
+ from .test_files_generator import create_test_files
10
+ from .config_generator import create_configuration_documentation, generate_enhanced_configurations
11
+ from .certificate_manager import generate_certificates_with_framework
12
+ from .test_runner import test_proxy_registration, run_full_test_suite
13
+ from .environment_setup import setup_test_environment
14
+
15
+ __all__ = [
16
+ "ConfigurationValidator",
17
+ "create_test_files",
18
+ "create_configuration_documentation",
19
+ "generate_enhanced_configurations",
20
+ "generate_certificates_with_framework",
21
+ "test_proxy_registration",
22
+ "run_full_test_suite",
23
+ "setup_test_environment",
24
+ ]
@@ -0,0 +1,215 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Certificate manager for MCP Proxy Adapter test environment setup.
6
+ """
7
+
8
+ import os
9
+ import subprocess
10
+ from pathlib import Path
11
+ from typing import bool
12
+
13
+
14
+ def generate_certificates_with_framework(output_dir: Path) -> bool:
15
+ """
16
+ Generate certificates using mcp_security_framework if available.
17
+
18
+ Args:
19
+ output_dir: Directory to generate certificates in
20
+
21
+ Returns:
22
+ True if certificates were generated successfully, False otherwise
23
+ """
24
+ try:
25
+ from mcp_security_framework.core.cert_manager import CertificateManager
26
+ CertificateConfig,
27
+ CAConfig,
28
+ ServerCertConfig,
29
+ ClientCertConfig,
30
+ )
31
+
32
+ print("🔐 Generating certificates using mcp_security_framework...")
33
+
34
+ # Create certificate directories
35
+ certs_dir = output_dir / "certs"
36
+ keys_dir = output_dir / "keys"
37
+ certs_dir.mkdir(parents=True, exist_ok=True)
38
+ keys_dir.mkdir(parents=True, exist_ok=True)
39
+
40
+ # Initialize certificate manager
41
+ cert_manager = CertificateManager()
42
+
43
+ # Generate CA certificate
44
+ ca_config = CAConfig(
45
+ common_name="MCP Test CA",
46
+ country="US",
47
+ state="Test State",
48
+ city="Test City",
49
+ organization="MCP Test Org",
50
+ organizational_unit="Test Unit",
51
+ validity_days=365
52
+ )
53
+
54
+ ca_cert_path = certs_dir / "ca_cert.pem"
55
+ ca_key_path = keys_dir / "ca_key.pem"
56
+
57
+ print("📜 Generating CA certificate...")
58
+ cert_manager.generate_ca_certificate(
59
+ ca_config,
60
+ str(ca_cert_path),
61
+ str(ca_key_path)
62
+ )
63
+
64
+ # Generate server certificate
65
+ server_config = ServerCertConfig(
66
+ common_name="localhost",
67
+ san_dns=["localhost", "127.0.0.1"],
68
+ san_ip=["127.0.0.1", "::1"],
69
+ validity_days=365
70
+ )
71
+
72
+ server_cert_path = certs_dir / "localhost_server.crt"
73
+ server_key_path = keys_dir / "server_key.pem"
74
+
75
+ print("🖥️ Generating server certificate...")
76
+ cert_manager.generate_server_certificate(
77
+ server_config,
78
+ str(server_cert_path),
79
+ str(server_key_path),
80
+ str(ca_cert_path),
81
+ str(ca_key_path)
82
+ )
83
+
84
+ # Generate client certificate
85
+ client_config = ClientCertConfig(
86
+ common_name="test-client",
87
+ validity_days=365
88
+ )
89
+
90
+ client_cert_path = certs_dir / "client_cert.pem"
91
+ client_key_path = keys_dir / "client_key.pem"
92
+
93
+ print("👤 Generating client certificate...")
94
+ cert_manager.generate_client_certificate(
95
+ client_config,
96
+ str(client_cert_path),
97
+ str(client_key_path),
98
+ str(ca_cert_path),
99
+ str(ca_key_path)
100
+ )
101
+
102
+ print("✅ Certificates generated successfully!")
103
+ print(f" CA Certificate: {ca_cert_path}")
104
+ print(f" Server Certificate: {server_cert_path}")
105
+ print(f" Client Certificate: {client_cert_path}")
106
+
107
+ return True
108
+
109
+ except ImportError:
110
+ print("⚠️ mcp_security_framework not available, using OpenSSL fallback...")
111
+ return _generate_certificates_with_openssl(output_dir)
112
+ except Exception as e:
113
+ print(f"❌ Error generating certificates with framework: {e}")
114
+ print("🔄 Falling back to OpenSSL...")
115
+ return _generate_certificates_with_openssl(output_dir)
116
+
117
+
118
+ def _generate_certificates_with_openssl(output_dir: Path) -> bool:
119
+ """
120
+ Generate certificates using OpenSSL as fallback.
121
+
122
+ Args:
123
+ output_dir: Directory to generate certificates in
124
+
125
+ Returns:
126
+ True if certificates were generated successfully, False otherwise
127
+ """
128
+ try:
129
+ print("🔐 Generating certificates using OpenSSL...")
130
+
131
+ # Create certificate directories
132
+ certs_dir = output_dir / "certs"
133
+ keys_dir = output_dir / "keys"
134
+ certs_dir.mkdir(parents=True, exist_ok=True)
135
+ keys_dir.mkdir(parents=True, exist_ok=True)
136
+
137
+ # Generate CA private key
138
+ ca_key_path = keys_dir / "ca_key.pem"
139
+ subprocess.run([
140
+ "openssl", "genrsa", "-out", str(ca_key_path), "2048"
141
+ ], check=True)
142
+
143
+ # Generate CA certificate
144
+ ca_cert_path = certs_dir / "ca_cert.pem"
145
+ subprocess.run([
146
+ "openssl", "req", "-new", "-x509", "-key", str(ca_key_path),
147
+ "-out", str(ca_cert_path), "-days", "365",
148
+ "-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=MCP Test CA"
149
+ ], check=True)
150
+
151
+ # Generate server private key
152
+ server_key_path = keys_dir / "server_key.pem"
153
+ subprocess.run([
154
+ "openssl", "genrsa", "-out", str(server_key_path), "2048"
155
+ ], check=True)
156
+
157
+ # Generate server certificate request
158
+ server_csr_path = certs_dir / "server.csr"
159
+ subprocess.run([
160
+ "openssl", "req", "-new", "-key", str(server_key_path),
161
+ "-out", str(server_csr_path),
162
+ "-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=localhost"
163
+ ], check=True)
164
+
165
+ # Generate server certificate
166
+ server_cert_path = certs_dir / "localhost_server.crt"
167
+ subprocess.run([
168
+ "openssl", "x509", "-req", "-in", str(server_csr_path),
169
+ "-CA", str(ca_cert_path), "-CAkey", str(ca_key_path),
170
+ "-out", str(server_cert_path), "-days", "365",
171
+ "-CAcreateserial"
172
+ ], check=True)
173
+
174
+ # Generate client private key
175
+ client_key_path = keys_dir / "client_key.pem"
176
+ subprocess.run([
177
+ "openssl", "genrsa", "-out", str(client_key_path), "2048"
178
+ ], check=True)
179
+
180
+ # Generate client certificate request
181
+ client_csr_path = certs_dir / "client.csr"
182
+ subprocess.run([
183
+ "openssl", "req", "-new", "-key", str(client_key_path),
184
+ "-out", str(client_csr_path),
185
+ "-subj", "/C=US/ST=Test/L=Test/O=Test/OU=Test/CN=test-client"
186
+ ], check=True)
187
+
188
+ # Generate client certificate
189
+ client_cert_path = certs_dir / "client_cert.pem"
190
+ subprocess.run([
191
+ "openssl", "x509", "-req", "-in", str(client_csr_path),
192
+ "-CA", str(ca_cert_path), "-CAkey", str(ca_key_path),
193
+ "-out", str(client_cert_path), "-days", "365"
194
+ ], check=True)
195
+
196
+ # Clean up CSR files
197
+ server_csr_path.unlink(missing_ok=True)
198
+ client_csr_path.unlink(missing_ok=True)
199
+
200
+ print("✅ Certificates generated successfully with OpenSSL!")
201
+ print(f" CA Certificate: {ca_cert_path}")
202
+ print(f" Server Certificate: {server_cert_path}")
203
+ print(f" Client Certificate: {client_cert_path}")
204
+
205
+ return True
206
+
207
+ except subprocess.CalledProcessError as e:
208
+ print(f"❌ OpenSSL command failed: {e}")
209
+ return False
210
+ except FileNotFoundError:
211
+ print("❌ OpenSSL not found. Please install OpenSSL or mcp_security_framework")
212
+ return False
213
+ except Exception as e:
214
+ print(f"❌ Error generating certificates with OpenSSL: {e}")
215
+ return False
@@ -0,0 +1,12 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Configuration generator for MCP Proxy Adapter test environment setup.
6
+ """
7
+
8
+ from pathlib import Path
9
+
10
+
11
+
12
+
@@ -0,0 +1,118 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Configuration validator for MCP Proxy Adapter test environment setup.
6
+ """
7
+
8
+ from typing import Dict, List, Any, Tuple
9
+
10
+
11
+ class ConfigurationValidator:
12
+ """
13
+ Validates MCP Proxy Adapter configurations for mutually exclusive settings
14
+ and protocol compatibility.
15
+ """
16
+
17
+ def __init__(self):
18
+ self.errors: List[str] = []
19
+ self.warnings: List[str] = []
20
+
21
+
22
+ def _validate_protocol_settings(
23
+ self, config: Dict[str, Any], config_name: str
24
+ ) -> None:
25
+ """Validate protocol configuration settings."""
26
+ protocols = config.get("protocols", {})
27
+
28
+ if not protocols.get("enabled", False):
29
+ self.warnings.append(
30
+ f"⚠️ {config_name}: Protocol middleware is disabled - all protocols will be allowed"
31
+ )
32
+ return
33
+
34
+ allowed_protocols = protocols.get("allowed_protocols", [])
35
+ if not allowed_protocols:
36
+ self.errors.append(
37
+ f"❌ {config_name}: No allowed protocols specified when protocol middleware is enabled"
38
+ )
39
+ return
40
+
41
+ # Check for invalid protocol combinations
42
+ if "http" in allowed_protocols and "https" in allowed_protocols:
43
+ self.warnings.append(
44
+ f"⚠️ {config_name}: Both HTTP and HTTPS protocols are allowed - consider security implications"
45
+ )
46
+
47
+ if "mtls" in allowed_protocols and "http" in allowed_protocols:
48
+ self.errors.append(
49
+ f"❌ {config_name}: mTLS and HTTP protocols are mutually exclusive - mTLS requires HTTPS"
50
+ )
51
+
52
+ def _validate_ssl_settings(self, config: Dict[str, Any], config_name: str) -> None:
53
+ """Validate SSL/TLS configuration settings."""
54
+ security = config.get("security", {})
55
+ ssl = security.get("ssl", {})
56
+
57
+ if not ssl.get("enabled", False):
58
+ return
59
+
60
+ # Check certificate file requirements
61
+ cert_file = ssl.get("server_cert_file")
62
+ key_file = ssl.get("server_key_file")
63
+
64
+ if not cert_file or not key_file:
65
+ self.errors.append(
66
+ f"❌ {config_name}: SSL enabled but server certificate or key file not specified"
67
+ )
68
+
69
+ # Check CA certificate requirements
70
+ ca_cert_file = ssl.get("ca_cert_file")
71
+ verify_server = ssl.get("verify_server", True)
72
+
73
+ if verify_server and not ca_cert_file:
74
+ self.warnings.append(
75
+ f"⚠️ {config_name}: Server verification enabled but no CA certificate specified"
76
+ )
77
+
78
+ def _validate_mtls_settings(self, config: Dict[str, Any], config_name: str) -> None:
79
+ """Validate mTLS configuration settings."""
80
+ security = config.get("security", {})
81
+ ssl = security.get("ssl", {})
82
+
83
+ if not ssl.get("enabled", False):
84
+ return
85
+
86
+ # Check if mTLS is configured
87
+ client_cert_file = ssl.get("client_cert_file")
88
+ client_key_file = ssl.get("client_key_file")
89
+ verify_client = ssl.get("verify_client", False)
90
+
91
+ if verify_client and (not client_cert_file or not client_key_file):
92
+ self.errors.append(
93
+ f"❌ {config_name}: Client verification enabled but client certificate or key file not specified"
94
+ )
95
+
96
+ # Check protocol compatibility
97
+ protocols = config.get("protocols", {})
98
+ if protocols.get("enabled", False):
99
+ allowed_protocols = protocols.get("allowed_protocols", [])
100
+ if verify_client and "mtls" not in allowed_protocols:
101
+ self.warnings.append(
102
+ f"⚠️ {config_name}: Client verification enabled but 'mtls' not in allowed protocols"
103
+ )
104
+
105
+ def _validate_auth_settings(self, config: Dict[str, Any], config_name: str) -> None:
106
+ """Validate authentication configuration settings."""
107
+ security = config.get("security", {})
108
+ auth = security.get("auth", {})
109
+
110
+ if not auth.get("enabled", False):
111
+ return
112
+
113
+ # Check token requirements
114
+ token_required = auth.get("token_required", False)
115
+ if token_required and not auth.get("token_secret"):
116
+ self.errors.append(
117
+ f"❌ {config_name}: Token authentication enabled but no token secret specified"
118
+ )
@@ -0,0 +1,62 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Environment setup for MCP Proxy Adapter test environment.
6
+ """
7
+
8
+ import shutil
9
+ from pathlib import Path
10
+ from typing import bool
11
+
12
+ from .config_generator import create_configuration_documentation, generate_enhanced_configurations
13
+ from .test_files_generator import create_test_files
14
+ from .certificate_manager import generate_certificates_with_framework
15
+
16
+
17
+
18
+
19
+ def _create_directory_structure(output_dir: Path) -> None:
20
+ """Create the required directory structure."""
21
+ directories = [
22
+ "configs",
23
+ "certs",
24
+ "keys",
25
+ "docs",
26
+ "examples",
27
+ "logs"
28
+ ]
29
+
30
+ for directory in directories:
31
+ dir_path = output_dir / directory
32
+ dir_path.mkdir(parents=True, exist_ok=True)
33
+ print(f" Created: {dir_path}")
34
+
35
+
36
+ def _copy_example_files(output_dir: Path) -> None:
37
+ """Copy example files from the package."""
38
+ try:
39
+ # Get package paths
40
+ package_path = Path(__file__).parent.parent.parent.parent
41
+ examples_path = package_path / "examples"
42
+
43
+ # Copy example files
44
+ examples_dest = output_dir / "examples"
45
+ if examples_path.exists():
46
+ shutil.copytree(examples_path, examples_dest, dirs_exist_ok=True)
47
+ print(f" Copied examples to: {examples_dest}")
48
+ else:
49
+ print(" ⚠️ Examples directory not found, skipping...")
50
+
51
+ except Exception as e:
52
+ print(f" ⚠️ Error copying example files: {e}")
53
+
54
+
55
+ def _create_setup_completion_marker(output_dir: Path) -> None:
56
+ """Create a marker file indicating setup completion."""
57
+ marker_file = output_dir / ".setup_complete"
58
+ with open(marker_file, "w", encoding="utf-8") as f:
59
+ f.write("MCP Proxy Adapter test environment setup completed successfully.\n")
60
+ f.write("Generated by setup_test_environment.py\n")
61
+
62
+ print(f" Created setup marker: {marker_file}")