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
@@ -1,5 +1,8 @@
1
1
  """
2
2
  Module for microservice configuration management.
3
+
4
+ Author: Vasiliy Zdanovskiy
5
+ email: vasilyvz@gmail.com
3
6
  """
4
7
 
5
8
  import json
@@ -67,7 +70,7 @@ class Config:
67
70
  "verify_client": False,
68
71
  "client_cert_required": False,
69
72
  "cipher_suites": ["TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"],
70
- "min_tls_version": "1.2",
73
+ "min_tls_version": "TLSv1.2",
71
74
  "max_tls_version": "1.3",
72
75
  "token_auth": {
73
76
  "enabled": False,
@@ -80,16 +83,16 @@ class Config:
80
83
  }
81
84
  },
82
85
  "roles": {
83
- "enabled": True,
84
- "config_file": "schemas/roles_schema.json",
86
+ "enabled": False,
87
+ "config_file": None,
85
88
  "default_policy": {
86
- "deny_by_default": True,
87
- "require_role_match": True,
89
+ "deny_by_default": False,
90
+ "require_role_match": False,
88
91
  "case_sensitive": False,
89
- "allow_wildcard": True
92
+ "allow_wildcard": False
90
93
  },
91
- "auto_load": True,
92
- "validation_enabled": True
94
+ "auto_load": False,
95
+ "validation_enabled": False
93
96
  },
94
97
  "transport": {
95
98
  "type": "http",
@@ -122,35 +125,92 @@ class Config:
122
125
  "security": {
123
126
  "framework": "mcp_security_framework",
124
127
  "enabled": True,
128
+ "debug": False,
129
+ "environment": "dev",
130
+ "version": "1.0.0",
125
131
  "auth": {
126
132
  "enabled": True,
127
133
  "methods": ["api_key"],
128
134
  "api_keys": {},
135
+ "user_roles": {},
129
136
  "jwt_secret": "",
130
- "jwt_algorithm": "HS256"
137
+ "jwt_algorithm": "HS256",
138
+ "jwt_expiry_hours": 24,
139
+ "certificate_auth": False,
140
+ "certificate_roles_oid": "1.3.6.1.4.1.99999.1.1",
141
+ "certificate_permissions_oid": "1.3.6.1.4.1.99999.1.2",
142
+ "basic_auth": False,
143
+ "oauth2_config": None,
144
+ "public_paths": ["/health", "/docs", "/openapi.json"],
145
+ "security_headers": None
131
146
  },
132
147
  "ssl": {
133
148
  "enabled": False,
134
149
  "cert_file": None,
135
150
  "key_file": None,
136
- "ca_cert": None,
151
+ "ca_cert_file": None,
152
+ "client_cert_file": None,
153
+ "client_key_file": None,
154
+ "verify_mode": "CERT_NONE",
137
155
  "min_tls_version": "TLSv1.2",
138
- "verify_client": False,
139
- "client_cert_required": False
156
+ "max_tls_version": None,
157
+ "cipher_suite": None,
158
+ "check_hostname": True,
159
+ "check_expiry": True,
160
+ "expiry_warning_days": 30
161
+ },
162
+ "certificates": {
163
+ "enabled": False,
164
+ "ca_cert_path": None,
165
+ "ca_key_path": None,
166
+ "cert_storage_path": "./certs",
167
+ "key_storage_path": "./keys",
168
+ "default_validity_days": 365,
169
+ "key_size": 2048,
170
+ "hash_algorithm": "sha256",
171
+ "crl_enabled": False,
172
+ "crl_path": None,
173
+ "crl_validity_days": 30,
174
+ "auto_renewal": False,
175
+ "renewal_threshold_days": 30
140
176
  },
141
177
  "permissions": {
142
- "enabled": True,
143
- "roles_file": "roles.json",
144
- "default_role": "user",
145
- "deny_by_default": True
178
+ "enabled": False,
179
+ "roles_file": None,
180
+ "default_role": "guest",
181
+ "admin_role": "admin",
182
+ "role_hierarchy": {},
183
+ "permission_cache_enabled": False,
184
+ "permission_cache_ttl": 300,
185
+ "wildcard_permissions": False,
186
+ "strict_mode": False,
187
+ "roles": None
146
188
  },
147
189
  "rate_limit": {
148
190
  "enabled": True,
149
- "requests_per_minute": 60,
150
- "requests_per_hour": 1000,
151
- "burst_limit": 10,
152
- "by_ip": True,
153
- "by_user": True
191
+ "default_requests_per_minute": 60,
192
+ "default_requests_per_hour": 1000,
193
+ "burst_limit": 2,
194
+ "window_size_seconds": 60,
195
+ "storage_backend": "memory",
196
+ "redis_config": None,
197
+ "cleanup_interval": 300,
198
+ "exempt_paths": ["/health", "/docs", "/openapi.json"],
199
+ "exempt_roles": ["admin"]
200
+ },
201
+ "logging": {
202
+ "enabled": True,
203
+ "level": "INFO",
204
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
205
+ "date_format": "%Y-%m-%d %H:%M:%S",
206
+ "file_path": None,
207
+ "max_file_size": 10,
208
+ "backup_count": 5,
209
+ "console_output": True,
210
+ "json_format": False,
211
+ "include_timestamp": True,
212
+ "include_level": True,
213
+ "include_module": True
154
214
  }
155
215
  }
156
216
  }
@@ -0,0 +1,326 @@
1
+ """
2
+ Application Factory for MCP Proxy Adapter
3
+
4
+ This module provides a factory function for creating and running MCP Proxy Adapter servers
5
+ with proper configuration validation and initialization.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import logging
12
+ import sys
13
+ from pathlib import Path
14
+ from typing import Optional, Dict, Any
15
+
16
+ from mcp_proxy_adapter.api.app import create_app
17
+ from mcp_proxy_adapter.core.logging import setup_logging, get_logger
18
+ from mcp_proxy_adapter.core.server_adapter import UnifiedServerRunner
19
+ from mcp_proxy_adapter.config import config
20
+ from mcp_proxy_adapter.commands.builtin_commands import register_builtin_commands
21
+
22
+ logger = get_logger("app_factory")
23
+
24
+
25
+ def create_and_run_server(
26
+ config_path: Optional[str] = None,
27
+ log_config_path: Optional[str] = None,
28
+ title: str = "MCP Proxy Adapter Server",
29
+ description: str = "Model Context Protocol Proxy Adapter with Security Framework",
30
+ version: str = "1.0.0",
31
+ host: str = "0.0.0.0",
32
+ log_level: str = "info",
33
+ engine: Optional[str] = None
34
+ ) -> None:
35
+ """
36
+ Create and run MCP Proxy Adapter server with proper validation.
37
+
38
+ This factory function validates all configuration files, sets up logging,
39
+ initializes the application, and starts the server with optimal settings.
40
+
41
+ Args:
42
+ config_path: Path to configuration file (JSON)
43
+ log_config_path: Path to logging configuration file (optional)
44
+ title: Application title for OpenAPI schema
45
+ description: Application description for OpenAPI schema
46
+ version: Application version
47
+ host: Server host address
48
+ port: Server port
49
+ log_level: Logging level
50
+ engine: Specific server engine to use (optional)
51
+
52
+ Raises:
53
+ SystemExit: If configuration validation fails or server cannot start
54
+ """
55
+ print("šŸš€ MCP Proxy Adapter Server Factory")
56
+ print("=" * 60)
57
+ print(f"šŸ“‹ Title: {title}")
58
+ print(f"šŸ“ Description: {description}")
59
+ print(f"šŸ”¢ Version: {version}")
60
+ print(f"🌐 Host: {host}")
61
+ print(f"šŸ“Š Log Level: {log_level}")
62
+ print("=" * 60)
63
+ print()
64
+
65
+ # 1. Validate and load configuration file
66
+ app_config = None
67
+ if config_path:
68
+ config_file = Path(config_path)
69
+ if not config_file.exists():
70
+ print(f"āŒ Configuration file not found: {config_path}")
71
+ print(" Please provide a valid path to config.json")
72
+ sys.exit(1)
73
+
74
+ try:
75
+ config.load_from_file(str(config_file))
76
+ app_config = config.get_all()
77
+ print(f"āœ… Configuration loaded from: {config_path}")
78
+
79
+ # Debug: Check what config.get_all() actually returns
80
+ print(f"šŸ” Debug: config.get_all() keys: {list(app_config.keys())}")
81
+ if "security" in app_config:
82
+ security_ssl = app_config["security"].get("ssl", {})
83
+ print(f"šŸ” Debug: config.get_all() security.ssl: {security_ssl}")
84
+
85
+ # Debug: Check if root ssl section exists after loading
86
+ if "ssl" in app_config:
87
+ print(f"šŸ” Debug: Root SSL section after loading: enabled={app_config['ssl'].get('enabled', False)}")
88
+ print(f"šŸ” Debug: Root SSL section after loading: cert_file={app_config['ssl'].get('cert_file')}")
89
+ print(f"šŸ” Debug: Root SSL section after loading: key_file={app_config['ssl'].get('key_file')}")
90
+ else:
91
+ print(f"šŸ” Debug: No root SSL section after loading")
92
+
93
+ # Debug: Check app_config immediately after get_all()
94
+ if app_config and "security" in app_config:
95
+ ssl_config = app_config["security"].get("ssl", {})
96
+ print(f"šŸ” Debug: app_config after get_all(): SSL enabled={ssl_config.get('enabled', False)}")
97
+ print(f"šŸ” Debug: app_config after get_all(): SSL cert_file={ssl_config.get('cert_file')}")
98
+ print(f"šŸ” Debug: app_config after get_all(): SSL key_file={ssl_config.get('key_file')}")
99
+
100
+ # Debug: Check SSL configuration after loading
101
+ if app_config and "security" in app_config:
102
+ ssl_config = app_config["security"].get("ssl", {})
103
+ print(f"šŸ” Debug: SSL config after loading: enabled={ssl_config.get('enabled', False)}")
104
+ print(f"šŸ” Debug: SSL config after loading: cert_file={ssl_config.get('cert_file')}")
105
+ print(f"šŸ” Debug: SSL config after loading: key_file={ssl_config.get('key_file')}")
106
+
107
+ # Debug: Check if SSL config is correct
108
+ if ssl_config.get('enabled', False):
109
+ print(f"šŸ” Debug: SSL config is enabled and correct")
110
+ else:
111
+ print(f"šŸ” Debug: SSL config is disabled or incorrect")
112
+ # Try to get SSL config from root level
113
+ root_ssl = app_config.get("ssl", {})
114
+ print(f"šŸ” Debug: Root SSL config: enabled={root_ssl.get('enabled', False)}")
115
+ print(f"šŸ” Debug: Root SSL config: cert_file={root_ssl.get('cert_file')}")
116
+ print(f"šŸ” Debug: Root SSL config: key_file={root_ssl.get('key_file')}")
117
+
118
+ # Validate security framework configuration only if enabled
119
+ security_config = app_config.get("security", {})
120
+ if security_config.get("enabled", False):
121
+ framework = security_config.get("framework", "mcp_security_framework")
122
+ print(f"šŸ”’ Security framework: {framework}")
123
+
124
+ # Debug: Check SSL config before validation
125
+ ssl_config = security_config.get("ssl", {})
126
+ print(f"šŸ” Debug: SSL config before validation: enabled={ssl_config.get('enabled', False)}")
127
+
128
+ # Validate security configuration
129
+ from mcp_proxy_adapter.core.unified_config_adapter import UnifiedConfigAdapter
130
+ adapter = UnifiedConfigAdapter()
131
+ validation_result = adapter.validate_configuration(app_config)
132
+
133
+ # Debug: Check SSL config after validation
134
+ ssl_config = app_config.get("security", {}).get("ssl", {})
135
+ print(f"šŸ” Debug: SSL config after validation: enabled={ssl_config.get('enabled', False)}")
136
+
137
+ if not validation_result.is_valid:
138
+ print("āŒ Security configuration validation failed:")
139
+ for error in validation_result.errors:
140
+ print(f" - {error}")
141
+ sys.exit(1)
142
+
143
+ if validation_result.warnings:
144
+ print("āš ļø Security configuration warnings:")
145
+ for warning in validation_result.warnings:
146
+ print(f" - {warning}")
147
+
148
+ print("āœ… Security configuration validated successfully")
149
+ else:
150
+ print("šŸ”“ Security framework disabled")
151
+
152
+ except Exception as e:
153
+ print(f"āŒ Failed to load configuration from {config_path}: {e}")
154
+ sys.exit(1)
155
+ else:
156
+ print("āš ļø No configuration file provided, using defaults")
157
+ app_config = config.get_all()
158
+
159
+ # 2. Setup logging
160
+ try:
161
+ if log_config_path:
162
+ log_config_file = Path(log_config_path)
163
+ if not log_config_file.exists():
164
+ print(f"āŒ Log configuration file not found: {log_config_path}")
165
+ sys.exit(1)
166
+ setup_logging(log_config_path=str(log_config_file))
167
+ print(f"āœ… Logging configured from: {log_config_path}")
168
+ else:
169
+ setup_logging()
170
+ print("āœ… Logging configured with defaults")
171
+ except Exception as e:
172
+ print(f"āŒ Failed to setup logging: {e}")
173
+ sys.exit(1)
174
+
175
+ # 3. Register built-in commands
176
+ try:
177
+ builtin_count = register_builtin_commands()
178
+ print(f"āœ… Registered {builtin_count} built-in commands")
179
+ except Exception as e:
180
+ print(f"āŒ Failed to register built-in commands: {e}")
181
+ sys.exit(1)
182
+
183
+ # 4. Create FastAPI application with configuration
184
+ try:
185
+ # Debug: Check app_config before passing to create_app
186
+ if app_config and "security" in app_config:
187
+ ssl_config = app_config["security"].get("ssl", {})
188
+ print(f"šŸ” Debug: app_config before create_app: SSL enabled={ssl_config.get('enabled', False)}")
189
+ print(f"šŸ” Debug: app_config before create_app: SSL cert_file={ssl_config.get('cert_file')}")
190
+ print(f"šŸ” Debug: app_config before create_app: SSL key_file={ssl_config.get('key_file')}")
191
+
192
+ app = create_app(
193
+ title=title,
194
+ description=description,
195
+ version=version,
196
+ app_config=app_config, # Pass configuration to create_app
197
+ config_path=config_path # Pass config path to preserve SSL settings
198
+ )
199
+ print("āœ… FastAPI application created successfully")
200
+ except Exception as e:
201
+ print(f"āŒ Failed to create FastAPI application: {e}")
202
+ sys.exit(1)
203
+
204
+ # 5. Create server configuration
205
+ # Get port from config if available, otherwise use default
206
+ server_port = app_config.get("server", {}).get("port", 8000) if app_config else 8000
207
+ print(f"šŸ”Œ Port: {server_port}")
208
+
209
+ server_config = {
210
+ "host": host,
211
+ "port": server_port,
212
+ "log_level": log_level,
213
+ "reload": False
214
+ }
215
+
216
+ # Add SSL configuration if present
217
+ print(f"šŸ” Debug: app_config keys: {list(app_config.keys()) if app_config else 'None'}")
218
+
219
+ # Check for SSL config in root section first (higher priority)
220
+ if app_config and "ssl" in app_config:
221
+ print(f"šŸ” Debug: SSL config found in root: {app_config['ssl']}")
222
+ print(f"šŸ” Debug: SSL enabled: {app_config['ssl'].get('enabled', False)}")
223
+ if app_config["ssl"].get("enabled", False):
224
+ ssl_config = app_config["ssl"]
225
+ # Add SSL config directly to server_config for Hypercorn
226
+ server_config["certfile"] = ssl_config.get("cert_file")
227
+ server_config["keyfile"] = ssl_config.get("key_file")
228
+ server_config["ca_certs"] = ssl_config.get("ca_cert_file")
229
+ server_config["verify_mode"] = ssl_config.get("verify_mode")
230
+ print(f"šŸ”’ SSL enabled: {ssl_config.get('cert_file', 'N/A')}")
231
+ print(f"šŸ”’ SSL enabled: cert={ssl_config.get('cert_file')}, key={ssl_config.get('key_file')}")
232
+ print(f"šŸ”’ Server config SSL: certfile={server_config.get('certfile')}, keyfile={server_config.get('keyfile')}, ca_certs={server_config.get('ca_certs')}, verify_mode={server_config.get('verify_mode')}")
233
+
234
+ # Check for SSL config in security section (fallback)
235
+ if app_config and "security" in app_config:
236
+ security_config = app_config["security"]
237
+ print(f"šŸ” Debug: security_config keys: {list(security_config.keys())}")
238
+ if "ssl" in security_config:
239
+ print(f"šŸ” Debug: SSL config found in security: {security_config['ssl']}")
240
+ print(f"šŸ” Debug: SSL enabled: {security_config['ssl'].get('enabled', False)}")
241
+ if security_config["ssl"].get("enabled", False):
242
+ ssl_config = security_config["ssl"]
243
+ # Add SSL config directly to server_config for Hypercorn
244
+ server_config["certfile"] = ssl_config.get("cert_file")
245
+ server_config["keyfile"] = ssl_config.get("key_file")
246
+ server_config["ca_certs"] = ssl_config.get("ca_cert_file")
247
+ server_config["verify_mode"] = ssl_config.get("verify_mode")
248
+ print(f"šŸ”’ SSL enabled: {ssl_config.get('cert_file', 'N/A')}")
249
+ print(f"šŸ”’ SSL enabled: cert={ssl_config.get('cert_file')}, key={ssl_config.get('key_file')}")
250
+ print(f"šŸ”’ Server config SSL: certfile={server_config.get('certfile')}, keyfile={server_config.get('keyfile')}, ca_certs={server_config.get('ca_certs')}, verify_mode={server_config.get('verify_mode')}")
251
+ print(f"šŸ” Debug: SSL config found in root: {app_config['ssl']}")
252
+ print(f"šŸ” Debug: SSL enabled: {app_config['ssl'].get('enabled', False)}")
253
+ if app_config["ssl"].get("enabled", False):
254
+ ssl_config = app_config["ssl"]
255
+ # Add SSL config directly to server_config for Hypercorn
256
+ server_config["certfile"] = ssl_config.get("cert_file")
257
+ server_config["keyfile"] = ssl_config.get("key_file")
258
+ server_config["ca_certs"] = ssl_config.get("ca_cert_file")
259
+ server_config["verify_mode"] = ssl_config.get("verify_mode")
260
+ print(f"šŸ”’ SSL enabled: {ssl_config.get('cert_file', 'N/A')}")
261
+ print(f"šŸ”’ SSL enabled: cert={ssl_config.get('cert_file')}, key={ssl_config.get('key_file')}")
262
+ print(f"šŸ”’ Server config SSL: certfile={server_config.get('certfile')}, keyfile={server_config.get('keyfile')}, ca_certs={server_config.get('ca_certs')}, verify_mode={server_config.get('verify_mode')}")
263
+
264
+ # 6. Start server
265
+ try:
266
+ print("šŸš€ Starting server...")
267
+ print(" Use Ctrl+C to stop the server")
268
+ print("=" * 60)
269
+
270
+ server_runner = UnifiedServerRunner()
271
+ server_runner.run_server(app, server_config, "hypercorn")
272
+
273
+ except KeyboardInterrupt:
274
+ print("\nšŸ›‘ Server stopped by user")
275
+ except Exception as e:
276
+ print(f"\nāŒ Failed to start server: {e}")
277
+ import traceback
278
+ traceback.print_exc()
279
+ sys.exit(1)
280
+
281
+
282
+ def validate_config_file(config_path: str) -> bool:
283
+ """
284
+ Validate configuration file exists and is readable.
285
+
286
+ Args:
287
+ config_path: Path to configuration file
288
+
289
+ Returns:
290
+ True if valid, False otherwise
291
+ """
292
+ try:
293
+ config_file = Path(config_path)
294
+ if not config_file.exists():
295
+ print(f"āŒ Configuration file not found: {config_path}")
296
+ return False
297
+
298
+ # Try to load configuration to validate JSON format
299
+ config.load_from_file(str(config_file))
300
+ return True
301
+
302
+ except Exception as e:
303
+ print(f"āŒ Configuration file validation failed: {e}")
304
+ return False
305
+
306
+
307
+ def validate_log_config_file(log_config_path: str) -> bool:
308
+ """
309
+ Validate logging configuration file exists and is readable.
310
+
311
+ Args:
312
+ log_config_path: Path to logging configuration file
313
+
314
+ Returns:
315
+ True if valid, False otherwise
316
+ """
317
+ try:
318
+ log_config_file = Path(log_config_path)
319
+ if not log_config_file.exists():
320
+ print(f"āŒ Log configuration file not found: {log_config_path}")
321
+ return False
322
+ return True
323
+
324
+ except Exception as e:
325
+ print(f"āŒ Log configuration file validation failed: {e}")
326
+ return False