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.
Files changed (264) hide show
  1. mcp_proxy_adapter/api/app.py +174 -80
  2. mcp_proxy_adapter/api/handlers.py +16 -5
  3. mcp_proxy_adapter/api/middleware/__init__.py +9 -4
  4. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  5. mcp_proxy_adapter/api/middleware/factory.py +36 -12
  6. mcp_proxy_adapter/api/middleware/protocol_middleware.py +32 -13
  7. mcp_proxy_adapter/api/middleware/unified_security.py +160 -0
  8. mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
  9. mcp_proxy_adapter/commands/__init__.py +7 -1
  10. mcp_proxy_adapter/commands/base.py +7 -4
  11. mcp_proxy_adapter/commands/builtin_commands.py +8 -2
  12. mcp_proxy_adapter/commands/command_registry.py +8 -0
  13. mcp_proxy_adapter/commands/echo_command.py +81 -0
  14. mcp_proxy_adapter/commands/help_command.py +21 -14
  15. mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
  16. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  17. mcp_proxy_adapter/commands/security_command.py +488 -0
  18. mcp_proxy_adapter/commands/ssl_setup_command.py +2 -2
  19. mcp_proxy_adapter/commands/token_management_command.py +1 -1
  20. mcp_proxy_adapter/config.py +81 -21
  21. mcp_proxy_adapter/core/app_factory.py +326 -0
  22. mcp_proxy_adapter/core/client_security.py +384 -0
  23. mcp_proxy_adapter/core/logging.py +8 -3
  24. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  25. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  26. mcp_proxy_adapter/core/protocol_manager.py +139 -8
  27. mcp_proxy_adapter/core/proxy_client.py +602 -0
  28. mcp_proxy_adapter/core/proxy_registration.py +299 -47
  29. mcp_proxy_adapter/core/security_adapter.py +12 -15
  30. mcp_proxy_adapter/core/security_integration.py +285 -0
  31. mcp_proxy_adapter/core/server_adapter.py +345 -0
  32. mcp_proxy_adapter/core/server_engine.py +364 -0
  33. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  34. mcp_proxy_adapter/docs/EN/TROUBLESHOOTING.md +285 -0
  35. mcp_proxy_adapter/docs/RU/TROUBLESHOOTING.md +285 -0
  36. mcp_proxy_adapter/examples/README.md +230 -97
  37. mcp_proxy_adapter/examples/README_EN.md +258 -0
  38. mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
  39. mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
  40. mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
  41. mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +43 -0
  42. mcp_proxy_adapter/examples/basic_framework/configs/https_no_protocol_middleware.json +36 -0
  43. mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +29 -0
  44. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_protocol_middleware.json +34 -0
  45. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
  46. mcp_proxy_adapter/examples/basic_framework/configs/mtls_simple.json +35 -0
  47. mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
  48. mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
  49. mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
  50. mcp_proxy_adapter/examples/cert_config.json +9 -0
  51. mcp_proxy_adapter/examples/certs/admin.crt +32 -0
  52. mcp_proxy_adapter/examples/certs/admin.key +52 -0
  53. mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
  54. mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
  55. mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
  56. mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
  57. mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
  58. mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
  59. mcp_proxy_adapter/examples/certs/client.crt +32 -0
  60. mcp_proxy_adapter/examples/certs/client.key +52 -0
  61. mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
  62. mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
  63. mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
  64. mcp_proxy_adapter/examples/certs/client_user.key +52 -0
  65. mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
  66. mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
  67. mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
  68. mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
  69. mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
  70. mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
  71. mcp_proxy_adapter/examples/certs/readonly.key +52 -0
  72. mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
  73. mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
  74. mcp_proxy_adapter/examples/certs/server.crt +32 -0
  75. mcp_proxy_adapter/examples/certs/server.key +52 -0
  76. mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
  77. mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
  78. mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
  79. mcp_proxy_adapter/examples/certs/user.crt +32 -0
  80. mcp_proxy_adapter/examples/certs/user.key +52 -0
  81. mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
  82. mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
  83. mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
  84. mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
  85. mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
  86. mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
  87. mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
  88. mcp_proxy_adapter/examples/commands/__init__.py +1 -0
  89. mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
  90. mcp_proxy_adapter/examples/debug_request_state.py +144 -0
  91. mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
  92. mcp_proxy_adapter/examples/demo_client.py +341 -0
  93. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
  94. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
  95. mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
  96. mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
  97. mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
  98. mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
  99. mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
  100. mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
  101. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
  102. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
  103. mcp_proxy_adapter/examples/full_application/main.py +138 -0
  104. mcp_proxy_adapter/examples/full_application/roles.json +21 -0
  105. mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
  106. mcp_proxy_adapter/examples/generate_certificates.py +121 -0
  107. mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
  108. mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
  109. mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
  110. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
  111. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
  112. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
  113. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
  114. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
  115. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
  116. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
  117. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
  118. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
  119. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
  120. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
  121. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
  122. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
  123. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
  124. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
  125. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
  126. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
  127. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
  128. mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
  129. mcp_proxy_adapter/examples/roles.json +38 -0
  130. mcp_proxy_adapter/examples/run_example.py +81 -0
  131. mcp_proxy_adapter/examples/run_security_tests.py +326 -0
  132. mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
  133. mcp_proxy_adapter/examples/security_test_client.py +743 -0
  134. mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
  135. mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
  136. mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
  137. mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
  138. mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
  139. mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
  140. mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
  141. mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
  142. mcp_proxy_adapter/examples/test_config_generator.py +110 -0
  143. mcp_proxy_adapter/examples/test_examples.py +344 -0
  144. mcp_proxy_adapter/examples/universal_client.py +628 -0
  145. mcp_proxy_adapter/main.py +21 -10
  146. mcp_proxy_adapter/utils/config_generator.py +727 -0
  147. mcp_proxy_adapter/version.py +5 -2
  148. mcp_proxy_adapter-6.1.1.dist-info/METADATA +205 -0
  149. mcp_proxy_adapter-6.1.1.dist-info/RECORD +197 -0
  150. mcp_proxy_adapter-6.1.1.dist-info/entry_points.txt +2 -0
  151. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.1.dist-info}/licenses/LICENSE +2 -2
  152. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  153. mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
  154. mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
  155. mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
  156. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  157. mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
  158. mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
  159. mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
  160. mcp_proxy_adapter/api/middleware/security.py +0 -376
  161. mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
  162. mcp_proxy_adapter/examples/__init__.py +0 -7
  163. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  164. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  165. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  166. mcp_proxy_adapter/examples/basic_server/config.json +0 -70
  167. mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
  168. mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
  169. mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
  170. mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
  171. mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
  172. mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
  173. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  174. mcp_proxy_adapter/examples/basic_server/server.py +0 -114
  175. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  176. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  177. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
  178. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  179. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  180. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  181. mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
  182. mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
  183. mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
  184. mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
  185. mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
  186. mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
  187. mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
  188. mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
  189. mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
  190. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  191. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  192. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  193. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  194. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  195. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  196. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  197. mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
  198. mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
  199. mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
  200. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  201. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  202. mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
  203. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  204. mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
  205. mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
  206. mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
  207. mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
  208. mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
  209. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  210. mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
  211. mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
  212. mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
  213. mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
  214. mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
  215. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  216. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  217. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  218. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  219. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  220. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  221. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  222. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  223. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  224. mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
  225. mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
  226. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  227. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  228. mcp_proxy_adapter/schemas/roles_schema.json +0 -162
  229. mcp_proxy_adapter/tests/__init__.py +0 -0
  230. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  231. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  232. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  233. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  234. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  235. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  236. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  237. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  238. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  239. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  240. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  241. mcp_proxy_adapter/tests/conftest.py +0 -131
  242. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  243. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  244. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  245. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  246. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  247. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  248. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  249. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  250. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  251. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  252. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  253. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  254. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  255. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  256. mcp_proxy_adapter/tests/test_config.py +0 -127
  257. mcp_proxy_adapter/tests/test_utils.py +0 -65
  258. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  259. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  260. mcp_proxy_adapter/tests/unit/test_config.py +0 -270
  261. mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
  262. mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
  263. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.1.dist-info}/WHEEL +0 -0
  264. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "server_url": "https://localhost:8443",
3
+ "timeout": 30,
4
+ "retry_attempts": 3,
5
+ "retry_delay": 1,
6
+ "security": {
7
+ "auth_method": "certificate",
8
+ "certificate": {
9
+ "enabled": true,
10
+ "cert_file": "./certs/client.crt",
11
+ "key_file": "./keys/client.key",
12
+ "ca_cert_file": "./certs/ca.crt"
13
+ },
14
+ "ssl": {
15
+ "enabled": true,
16
+ "check_hostname": true,
17
+ "ca_cert_file": "./certs/ca.crt",
18
+ "verify_mode": "CERT_REQUIRED",
19
+ "min_tls_version": "TLSv1.2"
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "server_url": "http://localhost:8000",
3
+ "timeout": 30,
4
+ "retry_attempts": 3,
5
+ "retry_delay": 1,
6
+ "security": {
7
+ "auth_method": "jwt",
8
+ "jwt": {
9
+ "username": "demo_user",
10
+ "password": "demo_password",
11
+ "secret": "your_jwt_secret_here",
12
+ "expiry_hours": 24
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "server_url": "http://localhost:8000",
3
+ "timeout": 30,
4
+ "retry_attempts": 3,
5
+ "retry_delay": 1,
6
+ "security": {
7
+ "auth_method": "none"
8
+ }
9
+ }
@@ -0,0 +1 @@
1
+ # Commands package
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple Certificate Creation Script
4
+
5
+ This script creates basic certificates for testing using OpenSSL directly.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import os
12
+ import subprocess
13
+ import sys
14
+ from pathlib import Path
15
+
16
+
17
+ class SimpleCertificateCreator:
18
+ """Create certificates using OpenSSL directly."""
19
+
20
+ def __init__(self):
21
+ self.project_root = Path(__file__).parent.parent.parent
22
+ self.certs_dir = self.project_root / "mcp_proxy_adapter" / "examples" / "certs"
23
+ self.keys_dir = self.project_root / "mcp_proxy_adapter" / "examples" / "keys"
24
+
25
+ # Create directories
26
+ self.certs_dir.mkdir(parents=True, exist_ok=True)
27
+ self.keys_dir.mkdir(parents=True, exist_ok=True)
28
+
29
+ def run_command(self, cmd: list, description: str) -> bool:
30
+ """Run a command and handle errors."""
31
+ try:
32
+ print(f"🔧 {description}...")
33
+ result = subprocess.run(
34
+ cmd,
35
+ cwd=self.project_root,
36
+ capture_output=True,
37
+ text=True,
38
+ check=True
39
+ )
40
+ print(f"✅ {description} completed successfully")
41
+ return True
42
+ except subprocess.CalledProcessError as e:
43
+ print(f"❌ {description} failed:")
44
+ print(f" Command: {' '.join(cmd)}")
45
+ print(f" Error: {e.stderr}")
46
+ return False
47
+ except Exception as e:
48
+ print(f"❌ {description} failed: {e}")
49
+ return False
50
+
51
+ def create_ca_certificate(self) -> bool:
52
+ """Create CA certificate using OpenSSL."""
53
+ ca_cert_path = self.certs_dir / "ca_cert.pem"
54
+ ca_key_path = self.keys_dir / "ca_key.pem"
55
+
56
+ if ca_cert_path.exists() and ca_key_path.exists():
57
+ print(f"ℹ️ CA certificate already exists: {ca_cert_path}")
58
+ return True
59
+
60
+ # Create CA private key
61
+ key_cmd = [
62
+ "openssl", "genrsa", "-out", str(ca_key_path), "2048"
63
+ ]
64
+ if not self.run_command(key_cmd, "Creating CA private key"):
65
+ return False
66
+
67
+ # Create CA certificate
68
+ cert_cmd = [
69
+ "openssl", "req", "-new", "-x509", "-days", "3650",
70
+ "-key", str(ca_key_path),
71
+ "-out", str(ca_cert_path),
72
+ "-subj", "/C=US/ST=Test State/L=Test City/O=Test Organization/CN=MCP Proxy Adapter Test CA"
73
+ ]
74
+ return self.run_command(cert_cmd, "Creating CA certificate")
75
+
76
+ def create_server_certificate(self) -> bool:
77
+ """Create server certificate using OpenSSL."""
78
+ server_cert_path = self.certs_dir / "server_cert.pem"
79
+ server_key_path = self.certs_dir / "server_key.pem"
80
+
81
+ if server_cert_path.exists() and server_key_path.exists():
82
+ print(f"ℹ️ Server certificate already exists: {server_cert_path}")
83
+ return True
84
+
85
+ # Create server private key
86
+ key_cmd = [
87
+ "openssl", "genrsa", "-out", str(server_key_path), "2048"
88
+ ]
89
+ if not self.run_command(key_cmd, "Creating server private key"):
90
+ return False
91
+
92
+ # Create server certificate signing request
93
+ csr_path = self.certs_dir / "server.csr"
94
+ csr_cmd = [
95
+ "openssl", "req", "-new",
96
+ "-key", str(server_key_path),
97
+ "-out", str(csr_path),
98
+ "-subj", "/C=US/ST=Test State/L=Test City/O=Test Organization/CN=localhost"
99
+ ]
100
+ if not self.run_command(csr_cmd, "Creating server CSR"):
101
+ return False
102
+
103
+ # Create server certificate
104
+ cert_cmd = [
105
+ "openssl", "x509", "-req", "-days", "730",
106
+ "-in", str(csr_path),
107
+ "-CA", str(self.certs_dir / "ca_cert.pem"),
108
+ "-CAkey", str(self.keys_dir / "ca_key.pem"),
109
+ "-CAcreateserial",
110
+ "-out", str(server_cert_path)
111
+ ]
112
+ success = self.run_command(cert_cmd, "Creating server certificate")
113
+
114
+ # Clean up CSR
115
+ if csr_path.exists():
116
+ csr_path.unlink()
117
+
118
+ return success
119
+
120
+ def create_client_certificate(self, name: str, common_name: str) -> bool:
121
+ """Create client certificate using OpenSSL."""
122
+ cert_path = self.certs_dir / f"{name}_cert.pem"
123
+ key_path = self.certs_dir / f"{name}_key.pem"
124
+
125
+ if cert_path.exists() and key_path.exists():
126
+ print(f"ℹ️ Client certificate {name} already exists: {cert_path}")
127
+ return True
128
+
129
+ # Create client private key
130
+ key_cmd = [
131
+ "openssl", "genrsa", "-out", str(key_path), "2048"
132
+ ]
133
+ if not self.run_command(key_cmd, f"Creating {name} private key"):
134
+ return False
135
+
136
+ # Create client certificate signing request
137
+ csr_path = self.certs_dir / f"{name}.csr"
138
+ csr_cmd = [
139
+ "openssl", "req", "-new",
140
+ "-key", str(key_path),
141
+ "-out", str(csr_path),
142
+ "-subj", f"/C=US/ST=Test State/L=Test City/O=Test Organization/CN={common_name}"
143
+ ]
144
+ if not self.run_command(csr_cmd, f"Creating {name} CSR"):
145
+ return False
146
+
147
+ # Create client certificate
148
+ cert_cmd = [
149
+ "openssl", "x509", "-req", "-days", "730",
150
+ "-in", str(csr_path),
151
+ "-CA", str(self.certs_dir / "ca_cert.pem"),
152
+ "-CAkey", str(self.keys_dir / "ca_key.pem"),
153
+ "-CAcreateserial",
154
+ "-out", str(cert_path)
155
+ ]
156
+ success = self.run_command(cert_cmd, f"Creating {name} certificate")
157
+
158
+ # Clean up CSR
159
+ if csr_path.exists():
160
+ csr_path.unlink()
161
+
162
+ return success
163
+
164
+ def create_legacy_certificates(self) -> bool:
165
+ """Create legacy certificate files for compatibility."""
166
+ legacy_files = [
167
+ ("client.crt", "client.key", "client"),
168
+ ("client_admin.crt", "client_admin.key", "admin"),
169
+ ("admin.crt", "admin.key", "admin"),
170
+ ("user.crt", "user.key", "user"),
171
+ ("readonly.crt", "readonly.key", "readonly")
172
+ ]
173
+
174
+ success = True
175
+ for cert_file, key_file, source_name in legacy_files:
176
+ cert_path = self.certs_dir / cert_file
177
+ key_path = self.certs_dir / key_file
178
+
179
+ if not cert_path.exists() or not key_path.exists():
180
+ source_cert = self.certs_dir / f"{source_name}_cert.pem"
181
+ source_key = self.certs_dir / f"{source_name}_key.pem"
182
+
183
+ if source_cert.exists() and source_key.exists():
184
+ self.run_command(["cp", str(source_cert), str(cert_path)], f"Creating {cert_file}")
185
+ self.run_command(["cp", str(source_key), str(key_path)], f"Creating {key_file}")
186
+ else:
187
+ print(f"⚠️ Source certificate {source_name} not found for {cert_file}")
188
+ success = False
189
+
190
+ return success
191
+
192
+ def validate_certificates(self) -> bool:
193
+ """Validate all created certificates."""
194
+ print("\n🔍 Validating certificates...")
195
+
196
+ cert_files = [
197
+ "ca_cert.pem",
198
+ "server_cert.pem",
199
+ "admin_cert.pem",
200
+ "user_cert.pem",
201
+ "readonly_cert.pem",
202
+ "guest_cert.pem",
203
+ "proxy_cert.pem"
204
+ ]
205
+
206
+ success = True
207
+ for cert_file in cert_files:
208
+ cert_path = self.certs_dir / cert_file
209
+ if cert_path.exists():
210
+ try:
211
+ result = subprocess.run(
212
+ ["openssl", "x509", "-in", str(cert_path), "-text", "-noout"],
213
+ capture_output=True,
214
+ text=True,
215
+ check=True
216
+ )
217
+ print(f"✅ {cert_file}: Valid")
218
+ except subprocess.CalledProcessError:
219
+ print(f"❌ {cert_file}: Invalid")
220
+ success = False
221
+ else:
222
+ print(f"⚠️ {cert_file}: Not found")
223
+
224
+ return success
225
+
226
+ def create_all(self) -> bool:
227
+ """Create all certificates."""
228
+ print("🔐 Creating All Certificates for Security Testing")
229
+ print("=" * 60)
230
+
231
+ success = True
232
+
233
+ # 1. Create CA certificate
234
+ if not self.create_ca_certificate():
235
+ success = False
236
+ print("❌ Cannot continue without CA certificate")
237
+ return False
238
+
239
+ # 2. Create server certificate
240
+ if not self.create_server_certificate():
241
+ success = False
242
+
243
+ # 3. Create client certificates
244
+ print("\n👥 Creating client certificates...")
245
+ client_certs = [
246
+ ("admin", "admin-client"),
247
+ ("user", "user-client"),
248
+ ("readonly", "readonly-client"),
249
+ ("guest", "guest-client"),
250
+ ("proxy", "proxy-client")
251
+ ]
252
+
253
+ for name, common_name in client_certs:
254
+ if not self.create_client_certificate(name, common_name):
255
+ success = False
256
+
257
+ # 4. Create legacy certificates
258
+ print("\n🔄 Creating legacy certificates...")
259
+ if not self.create_legacy_certificates():
260
+ success = False
261
+
262
+ # 5. Validate certificates
263
+ if not self.validate_certificates():
264
+ success = False
265
+
266
+ # Print summary
267
+ print("\n" + "=" * 60)
268
+ print("📊 CERTIFICATE CREATION SUMMARY")
269
+ print("=" * 60)
270
+
271
+ if success:
272
+ print("✅ All certificates created successfully!")
273
+ print(f"📁 Certificates directory: {self.certs_dir}")
274
+ print(f"🔑 Keys directory: {self.keys_dir}")
275
+ print("\n📋 Created certificates:")
276
+
277
+ cert_files = list(self.certs_dir.glob("*.pem")) + list(self.certs_dir.glob("*.crt"))
278
+ for cert_file in sorted(cert_files):
279
+ print(f" - {cert_file.name}")
280
+
281
+ key_files = list(self.keys_dir.glob("*.pem")) + list(self.keys_dir.glob("*.key"))
282
+ for key_file in sorted(key_files):
283
+ print(f" - {key_file.name}")
284
+ else:
285
+ print("❌ Some certificates failed to create")
286
+ print("Check the error messages above")
287
+
288
+ return success
289
+
290
+
291
+ def main():
292
+ """Main function."""
293
+ creator = SimpleCertificateCreator()
294
+
295
+ try:
296
+ success = creator.create_all()
297
+ sys.exit(0 if success else 1)
298
+ except KeyboardInterrupt:
299
+ print("\n⚠️ Certificate creation interrupted by user")
300
+ sys.exit(1)
301
+ except Exception as e:
302
+ print(f"\n❌ Certificate creation failed: {e}")
303
+ sys.exit(1)
304
+
305
+
306
+ if __name__ == "__main__":
307
+ main()
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Debug Request State - Проверка request.state
4
+
5
+ Этот скрипт проверяет, как middleware устанавливает информацию о пользователе в request.state.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import asyncio
12
+ import json
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ # Add project root to path
17
+ project_root = Path(__file__).parent.parent.parent
18
+ sys.path.insert(0, str(project_root))
19
+
20
+ from fastapi import FastAPI, Request
21
+ from fastapi.testclient import TestClient
22
+ from mcp_proxy_adapter.api.app import create_app
23
+
24
+
25
+ async def debug_request_state():
26
+ """Debug request state handling."""
27
+
28
+ print("🔍 ОТЛАДКА REQUEST.STATE")
29
+ print("=" * 50)
30
+
31
+ # Create test app with proper configuration
32
+ config_path = project_root / "mcp_proxy_adapter" / "examples" / "server_configs" / "config_http_token.json"
33
+
34
+ with open(config_path) as f:
35
+ config = json.load(f)
36
+
37
+ # Override global config for testing
38
+ import mcp_proxy_adapter.config
39
+ mcp_proxy_adapter.config.config = config
40
+
41
+ app = create_app(config)
42
+ client = TestClient(app)
43
+
44
+ print("📋 1. ТЕСТИРОВАНИЕ БЕЗ АУТЕНТИФИКАЦИИ")
45
+ print("-" * 30)
46
+
47
+ # Test without authentication
48
+ response = client.post("/cmd", json={
49
+ "jsonrpc": "2.0",
50
+ "method": "echo",
51
+ "params": {"message": "test"},
52
+ "id": 1
53
+ })
54
+
55
+ print(f"Status: {response.status_code}")
56
+ print(f"Response: {response.json()}")
57
+
58
+ print("\n📋 2. ТЕСТИРОВАНИЕ С ADMIN ТОКЕНОМ")
59
+ print("-" * 30)
60
+
61
+ # Test with admin token
62
+ response = client.post("/cmd",
63
+ json={
64
+ "jsonrpc": "2.0",
65
+ "method": "echo",
66
+ "params": {"message": "test"},
67
+ "id": 1
68
+ },
69
+ headers={"X-API-Key": "test-token-123"}
70
+ )
71
+
72
+ print(f"Status: {response.status_code}")
73
+ print(f"Response: {response.json()}")
74
+
75
+ print("\n📋 3. ТЕСТИРОВАНИЕ С USER ТОКЕНОМ")
76
+ print("-" * 30)
77
+
78
+ # Test with user token
79
+ response = client.post("/cmd",
80
+ json={
81
+ "jsonrpc": "2.0",
82
+ "method": "echo",
83
+ "params": {"message": "test"},
84
+ "id": 1
85
+ },
86
+ headers={"X-API-Key": "user-token-456"}
87
+ )
88
+
89
+ print(f"Status: {response.status_code}")
90
+ print(f"Response: {response.json()}")
91
+
92
+ print("\n📋 4. ТЕСТИРОВАНИЕ С READONLY ТОКЕНОМ")
93
+ print("-" * 30)
94
+
95
+ # Test with readonly token
96
+ response = client.post("/cmd",
97
+ json={
98
+ "jsonrpc": "2.0",
99
+ "method": "echo",
100
+ "params": {"message": "test"},
101
+ "id": 1
102
+ },
103
+ headers={"X-API-Key": "readonly-token-123"}
104
+ )
105
+
106
+ print(f"Status: {response.status_code}")
107
+ print(f"Response: {response.json()}")
108
+
109
+ print("\n📋 5. ТЕСТИРОВАНИЕ ROLE_TEST КОМАНДЫ")
110
+ print("-" * 30)
111
+
112
+ # Test role_test command with readonly token
113
+ response = client.post("/cmd",
114
+ json={
115
+ "jsonrpc": "2.0",
116
+ "method": "role_test",
117
+ "params": {"action": "write"},
118
+ "id": 1
119
+ },
120
+ headers={"X-API-Key": "readonly-token-123"}
121
+ )
122
+
123
+ print(f"Status: {response.status_code}")
124
+ print(f"Response: {response.json()}")
125
+
126
+ print("\n📋 6. АНАЛИЗ ПРОБЛЕМЫ")
127
+ print("-" * 30)
128
+
129
+ print("🔍 ПРОБЛЕМА: Readonly роль получает доступ к командам")
130
+ print("\n📋 ВОЗМОЖНЫЕ ПРИЧИНЫ:")
131
+ print("1. Framework middleware не устанавливает user info в request.state")
132
+ print("2. Нет проверки прав на уровне middleware")
133
+ print("3. Команды не проверяют права доступа")
134
+ print("4. Интеграция между middleware и командами не работает")
135
+
136
+ print("\n📋 РЕКОМЕНДАЦИИ:")
137
+ print("1. Добавить CommandPermissionMiddleware")
138
+ print("2. Убедиться, что framework middleware устанавливает user info")
139
+ print("3. Добавить проверку прав в команды")
140
+ print("4. Проверить интеграцию middleware")
141
+
142
+
143
+ if __name__ == "__main__":
144
+ asyncio.run(debug_request_state())