mcp-proxy-adapter 6.0.0__py3-none-any.whl → 6.1.0__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 (259) 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 +7 -2
  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/unified_security.py +152 -0
  7. mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
  8. mcp_proxy_adapter/commands/__init__.py +7 -1
  9. mcp_proxy_adapter/commands/base.py +7 -4
  10. mcp_proxy_adapter/commands/builtin_commands.py +8 -2
  11. mcp_proxy_adapter/commands/command_registry.py +8 -0
  12. mcp_proxy_adapter/commands/echo_command.py +81 -0
  13. mcp_proxy_adapter/commands/help_command.py +21 -14
  14. mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
  15. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  16. mcp_proxy_adapter/commands/security_command.py +488 -0
  17. mcp_proxy_adapter/commands/ssl_setup_command.py +2 -2
  18. mcp_proxy_adapter/commands/token_management_command.py +1 -1
  19. mcp_proxy_adapter/config.py +81 -21
  20. mcp_proxy_adapter/core/app_factory.py +326 -0
  21. mcp_proxy_adapter/core/client_security.py +384 -0
  22. mcp_proxy_adapter/core/logging.py +8 -3
  23. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  24. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  25. mcp_proxy_adapter/core/protocol_manager.py +9 -0
  26. mcp_proxy_adapter/core/proxy_client.py +602 -0
  27. mcp_proxy_adapter/core/proxy_registration.py +299 -47
  28. mcp_proxy_adapter/core/security_adapter.py +12 -15
  29. mcp_proxy_adapter/core/security_integration.py +277 -0
  30. mcp_proxy_adapter/core/server_adapter.py +345 -0
  31. mcp_proxy_adapter/core/server_engine.py +364 -0
  32. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  33. mcp_proxy_adapter/examples/README.md +230 -97
  34. mcp_proxy_adapter/examples/README_EN.md +258 -0
  35. mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
  36. mcp_proxy_adapter/examples/__pycache__/security_configurations.cpython-312.pyc +0 -0
  37. mcp_proxy_adapter/examples/__pycache__/security_test_client.cpython-312.pyc +0 -0
  38. mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
  39. mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
  40. mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +39 -0
  41. mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +25 -0
  42. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
  43. mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
  44. mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
  45. mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
  46. mcp_proxy_adapter/examples/cert_config.json +9 -0
  47. mcp_proxy_adapter/examples/certs/admin.crt +32 -0
  48. mcp_proxy_adapter/examples/certs/admin.key +52 -0
  49. mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
  50. mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
  51. mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
  52. mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
  53. mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
  54. mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
  55. mcp_proxy_adapter/examples/certs/client.crt +32 -0
  56. mcp_proxy_adapter/examples/certs/client.key +52 -0
  57. mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
  58. mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
  59. mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
  60. mcp_proxy_adapter/examples/certs/client_user.key +52 -0
  61. mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
  62. mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
  63. mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
  64. mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
  65. mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
  66. mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
  67. mcp_proxy_adapter/examples/certs/readonly.key +52 -0
  68. mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
  69. mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
  70. mcp_proxy_adapter/examples/certs/server.crt +32 -0
  71. mcp_proxy_adapter/examples/certs/server.key +52 -0
  72. mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
  73. mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
  74. mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
  75. mcp_proxy_adapter/examples/certs/user.crt +32 -0
  76. mcp_proxy_adapter/examples/certs/user.key +52 -0
  77. mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
  78. mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
  79. mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
  80. mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
  81. mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
  82. mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
  83. mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
  84. mcp_proxy_adapter/examples/commands/__init__.py +1 -0
  85. mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
  86. mcp_proxy_adapter/examples/debug_request_state.py +144 -0
  87. mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
  88. mcp_proxy_adapter/examples/demo_client.py +341 -0
  89. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
  90. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
  91. mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
  92. mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
  93. mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
  94. mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
  95. mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
  96. mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
  97. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
  98. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
  99. mcp_proxy_adapter/examples/full_application/main.py +138 -0
  100. mcp_proxy_adapter/examples/full_application/roles.json +21 -0
  101. mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
  102. mcp_proxy_adapter/examples/generate_certificates.py +121 -0
  103. mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
  104. mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
  105. mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
  106. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
  107. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
  108. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
  109. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
  110. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
  111. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
  112. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
  113. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
  114. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
  115. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
  116. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
  117. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
  118. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
  119. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
  120. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
  121. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
  122. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
  123. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
  124. mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
  125. mcp_proxy_adapter/examples/roles.json +38 -0
  126. mcp_proxy_adapter/examples/run_example.py +81 -0
  127. mcp_proxy_adapter/examples/run_security_tests.py +326 -0
  128. mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
  129. mcp_proxy_adapter/examples/security_test_client.py +743 -0
  130. mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
  131. mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
  132. mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
  133. mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
  134. mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
  135. mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
  136. mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
  137. mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
  138. mcp_proxy_adapter/examples/test_examples.py +344 -0
  139. mcp_proxy_adapter/examples/universal_client.py +628 -0
  140. mcp_proxy_adapter/main.py +21 -10
  141. mcp_proxy_adapter/utils/config_generator.py +639 -0
  142. mcp_proxy_adapter/version.py +2 -1
  143. mcp_proxy_adapter-6.1.0.dist-info/METADATA +205 -0
  144. mcp_proxy_adapter-6.1.0.dist-info/RECORD +193 -0
  145. mcp_proxy_adapter-6.1.0.dist-info/entry_points.txt +2 -0
  146. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/licenses/LICENSE +2 -2
  147. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  148. mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
  149. mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
  150. mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
  151. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  152. mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
  153. mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
  154. mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
  155. mcp_proxy_adapter/api/middleware/security.py +0 -376
  156. mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
  157. mcp_proxy_adapter/examples/__init__.py +0 -7
  158. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  159. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  160. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  161. mcp_proxy_adapter/examples/basic_server/config.json +0 -70
  162. mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
  163. mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
  164. mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
  165. mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
  166. mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
  167. mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
  168. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  169. mcp_proxy_adapter/examples/basic_server/server.py +0 -114
  170. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  171. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  172. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
  173. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  174. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  175. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  176. mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
  177. mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
  178. mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
  179. mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
  180. mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
  181. mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
  182. mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
  183. mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
  184. mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
  185. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  186. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  187. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  188. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  189. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  190. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  191. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  192. mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
  193. mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
  194. mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
  195. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  196. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  197. mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
  198. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  199. mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
  200. mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
  201. mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
  202. mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
  203. mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
  204. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  205. mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
  206. mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
  207. mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
  208. mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
  209. mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
  210. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  211. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  212. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  213. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  214. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  215. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  216. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  217. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  218. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  219. mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
  220. mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
  221. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  222. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  223. mcp_proxy_adapter/schemas/roles_schema.json +0 -162
  224. mcp_proxy_adapter/tests/__init__.py +0 -0
  225. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  226. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  227. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  228. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  229. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  230. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  231. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  232. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  233. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  234. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  235. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  236. mcp_proxy_adapter/tests/conftest.py +0 -131
  237. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  238. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  239. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  240. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  241. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  242. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  243. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  244. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  245. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  246. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  247. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  248. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  249. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  250. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  251. mcp_proxy_adapter/tests/test_config.py +0 -127
  252. mcp_proxy_adapter/tests/test_utils.py +0 -65
  253. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  254. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  255. mcp_proxy_adapter/tests/unit/test_config.py +0 -270
  256. mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
  257. mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
  258. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/WHEEL +0 -0
  259. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.0.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