mcp-proxy-adapter 6.0.0__py3-none-any.whl → 6.0.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 (212) hide show
  1. mcp_proxy_adapter/__main__.py +27 -7
  2. mcp_proxy_adapter/api/app.py +209 -79
  3. mcp_proxy_adapter/api/handlers.py +16 -5
  4. mcp_proxy_adapter/api/middleware/__init__.py +14 -9
  5. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  6. mcp_proxy_adapter/api/middleware/factory.py +36 -12
  7. mcp_proxy_adapter/api/middleware/protocol_middleware.py +84 -18
  8. mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
  9. mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
  10. mcp_proxy_adapter/commands/__init__.py +7 -1
  11. mcp_proxy_adapter/commands/base.py +7 -4
  12. mcp_proxy_adapter/commands/builtin_commands.py +8 -2
  13. mcp_proxy_adapter/commands/command_registry.py +8 -0
  14. mcp_proxy_adapter/commands/echo_command.py +81 -0
  15. mcp_proxy_adapter/commands/health_command.py +1 -1
  16. mcp_proxy_adapter/commands/help_command.py +21 -14
  17. mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
  18. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  19. mcp_proxy_adapter/commands/security_command.py +488 -0
  20. mcp_proxy_adapter/commands/ssl_setup_command.py +234 -351
  21. mcp_proxy_adapter/commands/token_management_command.py +1 -1
  22. mcp_proxy_adapter/config.py +323 -40
  23. mcp_proxy_adapter/core/app_factory.py +410 -0
  24. mcp_proxy_adapter/core/app_runner.py +272 -0
  25. mcp_proxy_adapter/core/certificate_utils.py +291 -73
  26. mcp_proxy_adapter/core/client.py +574 -0
  27. mcp_proxy_adapter/core/client_manager.py +284 -0
  28. mcp_proxy_adapter/core/client_security.py +384 -0
  29. mcp_proxy_adapter/core/logging.py +8 -3
  30. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  31. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  32. mcp_proxy_adapter/core/protocol_manager.py +169 -10
  33. mcp_proxy_adapter/core/proxy_client.py +602 -0
  34. mcp_proxy_adapter/core/proxy_registration.py +299 -47
  35. mcp_proxy_adapter/core/security_adapter.py +12 -15
  36. mcp_proxy_adapter/core/security_integration.py +286 -0
  37. mcp_proxy_adapter/core/server_adapter.py +282 -0
  38. mcp_proxy_adapter/core/server_engine.py +270 -0
  39. mcp_proxy_adapter/core/ssl_utils.py +13 -12
  40. mcp_proxy_adapter/core/transport_manager.py +5 -5
  41. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  42. mcp_proxy_adapter/examples/__init__.py +13 -4
  43. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  44. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  45. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  46. mcp_proxy_adapter/examples/basic_framework/main.py +44 -0
  47. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  48. mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
  49. mcp_proxy_adapter/examples/debug_request_state.py +112 -0
  50. mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
  51. mcp_proxy_adapter/examples/demo_client.py +275 -0
  52. mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
  53. mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
  54. mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
  55. mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
  56. mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
  57. mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
  58. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
  59. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  60. mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
  61. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
  62. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  63. mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
  64. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
  65. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  66. mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
  67. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
  68. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  69. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
  70. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
  71. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  72. mcp_proxy_adapter/examples/full_application/main.py +173 -0
  73. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
  74. mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
  75. mcp_proxy_adapter/examples/generate_certificates.py +177 -0
  76. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
  77. mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
  78. mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
  79. mcp_proxy_adapter/examples/run_example.py +59 -0
  80. mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
  81. mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
  82. mcp_proxy_adapter/examples/run_security_tests.py +544 -0
  83. mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
  84. mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
  85. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
  86. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
  87. mcp_proxy_adapter/examples/security_test_client.py +782 -0
  88. mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
  89. mcp_proxy_adapter/examples/test_config.py +148 -0
  90. mcp_proxy_adapter/examples/test_config_generator.py +86 -0
  91. mcp_proxy_adapter/examples/test_examples.py +281 -0
  92. mcp_proxy_adapter/examples/universal_client.py +620 -0
  93. mcp_proxy_adapter/main.py +66 -148
  94. mcp_proxy_adapter/utils/config_generator.py +1008 -0
  95. mcp_proxy_adapter/version.py +5 -2
  96. mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
  97. mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
  98. mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
  99. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
  100. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  101. mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
  102. mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
  103. mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
  104. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  105. mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
  106. mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
  107. mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
  108. mcp_proxy_adapter/api/middleware/security.py +0 -376
  109. mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
  110. mcp_proxy_adapter/examples/README.md +0 -124
  111. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  112. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  113. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  114. mcp_proxy_adapter/examples/basic_server/config.json +0 -70
  115. mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
  116. mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
  117. mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
  118. mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
  119. mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
  120. mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
  121. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  122. mcp_proxy_adapter/examples/basic_server/server.py +0 -114
  123. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  124. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  125. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
  126. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  127. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  128. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  129. mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
  130. mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
  131. mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
  132. mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
  133. mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
  134. mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
  135. mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
  136. mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
  137. mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
  138. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  139. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  140. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  141. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  142. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  143. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  144. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  145. mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
  146. mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
  147. mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
  148. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  149. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  150. mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
  151. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  152. mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
  153. mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
  154. mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
  155. mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
  156. mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
  157. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  158. mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
  159. mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
  160. mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
  161. mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
  162. mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
  163. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  164. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  165. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  166. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  167. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  168. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  169. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  170. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  171. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  172. mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
  173. mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
  174. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  175. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  176. mcp_proxy_adapter/schemas/roles_schema.json +0 -162
  177. mcp_proxy_adapter/tests/__init__.py +0 -0
  178. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  179. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  180. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  181. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  182. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  183. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  184. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  185. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  186. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  187. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  188. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  189. mcp_proxy_adapter/tests/conftest.py +0 -131
  190. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  191. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  192. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  193. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  194. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  195. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  196. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  197. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  198. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  199. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  200. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  201. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  202. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  203. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  204. mcp_proxy_adapter/tests/test_config.py +0 -127
  205. mcp_proxy_adapter/tests/test_utils.py +0 -65
  206. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  207. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  208. mcp_proxy_adapter/tests/unit/test_config.py +0 -270
  209. mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
  210. mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
  211. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
  212. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,140 @@
1
+ mcp_proxy_adapter/__init__.py,sha256=B7m1YWyv_Wb87-Q-JqVpHQgwajnfIgDyZ_iIxzdTbBY,1021
2
+ mcp_proxy_adapter/__main__.py,sha256=-Wp1myP9DzJNB9j97mj62C8kFk5YUbCmd0e7Rnwte0A,769
3
+ mcp_proxy_adapter/config.py,sha256=ss6A-7Ef1I7iyZ-h-bzGWGwddB47642wEhN7uwnt5bk,21563
4
+ mcp_proxy_adapter/custom_openapi.py,sha256=jYUrCy8C1mShh3sjKj-JkzSMLAvxDLTvtzSJFj5HUNg,15023
5
+ mcp_proxy_adapter/main.py,sha256=9qt_pEQdq8roUc73CumfDn6jDWP_NyfdE1lCGEynv5I,2841
6
+ mcp_proxy_adapter/openapi.py,sha256=36vOEbJjGnVZR6hUhl6mHCD29HYOEFKo2bL0JdGSm-4,13952
7
+ mcp_proxy_adapter/version.py,sha256=he5ZytTjuzxFCrKQ9AxOJw6hhMuKvgK4oyLQ4ErooZQ,76
8
+ mcp_proxy_adapter/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ mcp_proxy_adapter/api/app.py,sha256=khl4kaI4mJ6dNbfAK7hR97Ek-eWC9NBeuXHr6GVbLoU,28911
10
+ mcp_proxy_adapter/api/handlers.py,sha256=DcZT7MVBV33q-0EJ0iFqxE0VgBkFt6d_SqoRkntwyvc,8477
11
+ mcp_proxy_adapter/api/schemas.py,sha256=xOmiSwHaapY6myEFnLu7o-LWVPM7vwmLYZXFo2c6NfE,12381
12
+ mcp_proxy_adapter/api/tool_integration.py,sha256=MrtX7vUXCGBBuZuOs3C6EF67R_U_0xMfOmlmsAz-wuE,10245
13
+ mcp_proxy_adapter/api/tools.py,sha256=rRCRN2I8Odd2biBJZKByQS15rAWf0XwLRZEHDELc7Tg,8116
14
+ mcp_proxy_adapter/api/middleware/__init__.py,sha256=2tkokajbmHLsOS_jKEgOJq-YekyIZahDWcQChMfeKdg,2146
15
+ mcp_proxy_adapter/api/middleware/base.py,sha256=aMV9YPLHkUnJECuQWYbnlEGaj6xUJFHZR_hJb0OKvu8,2282
16
+ mcp_proxy_adapter/api/middleware/command_permission_middleware.py,sha256=sSdHTZ-ZxtcV3fJmcweB3sqlQivrYO_FO0H835jnPFA,5076
17
+ mcp_proxy_adapter/api/middleware/error_handling.py,sha256=avIZTjXj1sNOT3ekKtLAYJKM7V4duX0BF9PW-j18dEY,7134
18
+ mcp_proxy_adapter/api/middleware/factory.py,sha256=yDo7f4E-YL7qQZgGApyk8HZfLYOnrpsNx-Eh3fJBikE,8404
19
+ mcp_proxy_adapter/api/middleware/logging.py,sha256=VvUUX7bN4davCzFO6GYbN1O4sgJjOspV-EBLE3xpwpc,4730
20
+ mcp_proxy_adapter/api/middleware/performance.py,sha256=dHBxTF43LEGXMKHMH3A8ybKmwAWURd_zswqq_oC4xbw,2454
21
+ mcp_proxy_adapter/api/middleware/protocol_middleware.py,sha256=iVjJrTEfKy15ZchQUo-Mu0hBg9kEP6vgzee_3PtWd6M,8115
22
+ mcp_proxy_adapter/api/middleware/transport_middleware.py,sha256=Esy2gGKpEV5RoUTilr1YKKTDc5jh5RxsomD0VXyR2pE,4396
23
+ mcp_proxy_adapter/api/middleware/unified_security.py,sha256=fDWUeIuHjYUngVnB8gVR9ES3IQSaY9VP2YPZGXATJlU,7617
24
+ mcp_proxy_adapter/api/middleware/user_info_middleware.py,sha256=CWZvwUqieNhC8_ArTvncRjFfU3RHusO-dMcUSvRv01A,6311
25
+ mcp_proxy_adapter/commands/__init__.py,sha256=r791wg4FKhWSi5rqA3vekDcGf5kr18pwF1woX-dnZKo,1525
26
+ mcp_proxy_adapter/commands/auth_validation_command.py,sha256=z612WJDVgZwaCrxdQhATwRc5i3qxH37MPuIV6SuZPn8,15083
27
+ mcp_proxy_adapter/commands/base.py,sha256=tunyrmt-LYJMQZslAZQor3KZvOrn1IYNpL5uOAnSdxc,15791
28
+ mcp_proxy_adapter/commands/builtin_commands.py,sha256=oloxk0itnY4Uy1a3ARXqHPm48RqkHxBbHqzXZ4bUGN8,3258
29
+ mcp_proxy_adapter/commands/catalog_manager.py,sha256=FVyF2Ky8DUmvFxjiem3YeC9ASFOzCZ9Lp2MsNobA1wI,34712
30
+ mcp_proxy_adapter/commands/cert_monitor_command.py,sha256=JWitmmHDeooWXt2fWLbcfAHDeHpsTL2AuBaoka7OWNE,24485
31
+ mcp_proxy_adapter/commands/certificate_management_command.py,sha256=4byTb1yCqTQCbNH_L4p_z3HithuugzI3a-H9gjiLDhg,24440
32
+ mcp_proxy_adapter/commands/command_registry.py,sha256=mPNhLnJ4L1lSyVzYXpUjeCBJkWIqEtlzpr9JcprHIf4,35260
33
+ mcp_proxy_adapter/commands/config_command.py,sha256=-Z6BGaEQTf859l56zZpHYBeZFeIVdpMYybDrd7LOPIg,3553
34
+ mcp_proxy_adapter/commands/dependency_container.py,sha256=Uz9OPRAUZN7tsVrMVgXgPQcsRD2N-e2Ixg9XarPOlnY,3410
35
+ mcp_proxy_adapter/commands/dependency_manager.py,sha256=lmY79MBkh-JRIPsYxSkdrUE9XHi4XBCbucaEMT0w6do,7683
36
+ mcp_proxy_adapter/commands/echo_command.py,sha256=R1oDNEAJSOIuODa4Nk3z4WJXhSxniNzaZtYHADlV310,2390
37
+ mcp_proxy_adapter/commands/health_command.py,sha256=cNUfvQI4MAJQK1wKfzv_snCCK-FkL-FulVSErkMA3qw,4585
38
+ mcp_proxy_adapter/commands/help_command.py,sha256=PuanwvYmVs64DhB71gaI5rBRi_ozJ6x8afr18bRpTk4,13482
39
+ mcp_proxy_adapter/commands/hooks.py,sha256=Gu5TDSgA9EBHexWMWze8wgT63i6-dMEEwG8edWbrX3U,10060
40
+ mcp_proxy_adapter/commands/key_management_command.py,sha256=qin-iYXksIXOkZEfmJpclJSOyKaz9qRinj9uVa8hkdk,19339
41
+ mcp_proxy_adapter/commands/load_command.py,sha256=2zwPOCSBck6mr5KehyyH8lPRAqYYGeUeIIJdbxMSoZk,5984
42
+ mcp_proxy_adapter/commands/plugins_command.py,sha256=Te6YQH0ukJWIHAAEJE5DmdAilpjO1QMDa_PexhfQLH0,8531
43
+ mcp_proxy_adapter/commands/protocol_management_command.py,sha256=XSrNPGagopM4SinrSmNFW12KLng7-Oc9q6NpiInJ-QI,8485
44
+ mcp_proxy_adapter/commands/proxy_registration_command.py,sha256=yqPKgpv8oPP9mn1Blo-2VRVoWUpMcMJ29stqy2Di7hk,15394
45
+ mcp_proxy_adapter/commands/reload_command.py,sha256=6yJduQlIgXhtDSH4Q8qmfR8wZW1RVC1WT1eBIpxzCNo,7507
46
+ mcp_proxy_adapter/commands/result.py,sha256=9iFyoRRZ17q3d822XTMNyqnBvWypyoyV0NiHtM2bCd4,5604
47
+ mcp_proxy_adapter/commands/role_test_command.py,sha256=Hr45vB3W8tg_GQ4FfKOEOxW10eEb-pApo2nOPjru61M,4281
48
+ mcp_proxy_adapter/commands/roles_management_command.py,sha256=JSMkW9-Hq9ncltUvBjolQdvSeTa1FY2hoU0oD2mBon4,22471
49
+ mcp_proxy_adapter/commands/security_command.py,sha256=zKTVtb8vL_DafRHtrLqC2Mhk_DjOQ-3YwhIUh8NXJfQ,18206
50
+ mcp_proxy_adapter/commands/settings_command.py,sha256=hTBrFRABJDFYwnDf2ryfqoejUe06fM4XMOoiH0Exdyo,6407
51
+ mcp_proxy_adapter/commands/ssl_setup_command.py,sha256=wCWF7VhAB21m1FF7uR7r1mG1uLu6bFkfTfpHINM7LGI,13101
52
+ mcp_proxy_adapter/commands/token_management_command.py,sha256=7sl_fRUjWMRuP7NXoLjpLTB9wEg_aZU9dp5Ji9hbThA,18147
53
+ mcp_proxy_adapter/commands/transport_management_command.py,sha256=yv2lqUqJliYGIbYW7t0HQTrt5Cu2Y02rUjVzdznLtPk,4692
54
+ mcp_proxy_adapter/commands/unload_command.py,sha256=mhRZ23sJtTwUfWkjZzH8KDRpwxUX0kdu8LbAXAURRJc,5079
55
+ mcp_proxy_adapter/core/__init__.py,sha256=Ch50cV5Nd8m-HO9rMnVModajjwDK-OdUy7hxISDFkAM,800
56
+ mcp_proxy_adapter/core/app_factory.py,sha256=Xwyz40GNOWWa7ThArweawNBY4WI4bEI3_cj251mLHCM,17797
57
+ mcp_proxy_adapter/core/app_runner.py,sha256=JPpx9rKmaHAVdFnHRl2rXycptQkTSQ13Er7Qf1KZIA4,10614
58
+ mcp_proxy_adapter/core/auth_validator.py,sha256=lJxBVkoQWSk5CNtnPYMEJSsz4FhcXK-gB5QJ_OP9jEE,20937
59
+ mcp_proxy_adapter/core/certificate_utils.py,sha256=7VOhjRcygCToYgPTUt_MgcNILdpRBRBNZSFpeS_QrfA,39541
60
+ mcp_proxy_adapter/core/client.py,sha256=YxtaHvMoqKcjWJ-2mf2FH22wUGWUZjXMEKPqxypNOPE,21340
61
+ mcp_proxy_adapter/core/client_manager.py,sha256=sKEhapMpogqb54WIWEpz2bMjrX3wvYooX-a844IfCTU,9164
62
+ mcp_proxy_adapter/core/client_security.py,sha256=8isHpvv-7H85QzI8K3Pfyr_KdvpE2xYyIT4wqWrttNU,13575
63
+ mcp_proxy_adapter/core/config_converter.py,sha256=FAA2zx-yRgqMgzg73o9Aq5CEEfodNCeaA8Yluto4wAs,16985
64
+ mcp_proxy_adapter/core/config_validator.py,sha256=qDVmkRatuDeWylIPLjMq02Vpzff6DDTE_CstpzqGi7o,7773
65
+ mcp_proxy_adapter/core/errors.py,sha256=s34OxiIR4NCJu_pYSigKXqrIvRjUUK2OWw0X4dpDjIA,5151
66
+ mcp_proxy_adapter/core/logging.py,sha256=jQlFz52Xwapef6UD4p0acmaGFumD9XuexwW4frDN_ZM,9626
67
+ mcp_proxy_adapter/core/mtls_asgi.py,sha256=X2lAj3wk3L85amRCp_-10sqvZa5wJf_diXhwrrQReSo,5311
68
+ mcp_proxy_adapter/core/mtls_asgi_app.py,sha256=VeolP08TTaqYU5fGeaZexj6EBWBDugoVrEGXzJW4PuM,6406
69
+ mcp_proxy_adapter/core/protocol_manager.py,sha256=ISFRXjUuK4Q3uMbVB8-O_ozQSsDEH0PQA_HAKGeUrrw,14763
70
+ mcp_proxy_adapter/core/proxy_client.py,sha256=shP373Yelz7Fja22U6XnH0kT9XtPtWEFwOFlYFO97gw,22511
71
+ mcp_proxy_adapter/core/proxy_registration.py,sha256=87ko1vw61nHJGo0-xrObXiyQhrYK2K6nKr8rXID-j8c,19424
72
+ mcp_proxy_adapter/core/role_utils.py,sha256=wMoTVz3gF5fM7jozNMwsEwPkp1tui26M-t_KH1Oz8gs,12880
73
+ mcp_proxy_adapter/core/security_adapter.py,sha256=wZ3OH1WzhUdpN8N8CrGJSFFVNi474DqdazIqQ1T8PN4,13343
74
+ mcp_proxy_adapter/core/security_factory.py,sha256=4r7qvBq30XfosGD_b1ZHyNVLN8rOQ3NAKuaCOCEK8jA,8262
75
+ mcp_proxy_adapter/core/security_integration.py,sha256=6oJKVCL1CRnk3sTWX-PBzDjv737oe4QL-9r3l89kRkc,13715
76
+ mcp_proxy_adapter/core/server_adapter.py,sha256=8dhUlLxuYjaoNgMHieFCFgDRjxskP--Y5uoAhbN6RLw,9823
77
+ mcp_proxy_adapter/core/server_engine.py,sha256=SFENSDrVMlBD--HgKSRVklhrtLKSRSZhs_3UHxFCGbg,9540
78
+ mcp_proxy_adapter/core/settings.py,sha256=ZfUnmqD1tjAuaQo2VAF8evC1oHUit7gTu4WkTF0IMYI,10628
79
+ mcp_proxy_adapter/core/ssl_utils.py,sha256=_2mhpuoiRpSbUBifnQvtuziQfBRrXQUKtB58ALWTaqU,8220
80
+ mcp_proxy_adapter/core/transport_manager.py,sha256=ppcgjO-7Ulrk1ovlzlXVM89Iw4VOGA3awKgLf7FFAJ0,9518
81
+ mcp_proxy_adapter/core/unified_config_adapter.py,sha256=cpN_VrliIFGDH3JsfRkTlFdQvLcmuMYYedq0QEzlb0Y,22857
82
+ mcp_proxy_adapter/core/utils.py,sha256=ly8Ttg2v1OBukThJLxudRvmttU1hxJFLJUfat4b2dOI,3268
83
+ mcp_proxy_adapter/examples/__init__.py,sha256=k1F-EotAFbJ3JvK_rNgiH4bUztmxIWtYn0AfbAZ1ZGs,450
84
+ mcp_proxy_adapter/examples/create_certificates_simple.py,sha256=KhP-J98e3GRfEsueEtPlACyOVNWVVxRwBZWBMged_YA,25743
85
+ mcp_proxy_adapter/examples/debug_request_state.py,sha256=x_H3NIlkmIS6lZimvEM6kCXxGdpgFw99Sdui8qa_qeU,4347
86
+ mcp_proxy_adapter/examples/debug_role_chain.py,sha256=33l2Tk5mrcnwPFwqm2NTHcrWaJrXUU2wxW2I6Y4uIg4,8344
87
+ mcp_proxy_adapter/examples/demo_client.py,sha256=inic-FP5qG8oQXUaCrtEhmhac_PDZ1pcxp-M1cxSzwA,10240
88
+ mcp_proxy_adapter/examples/generate_all_certificates.py,sha256=rgcwqIkQ1eDfEIRFRXGIOz-jOSS1w0GPBRhYvMl6Vjc,16948
89
+ mcp_proxy_adapter/examples/generate_certificates.py,sha256=A34OHUEiFvINOHrm3_JiDSbp-WG-eQXIvKCsE8JAeXQ,6616
90
+ mcp_proxy_adapter/examples/generate_certificates_and_tokens.py,sha256=J0qHm_BMY8RYqfuwf7V7xKsHcsRJx8E7x-8JxmW5sPw,15988
91
+ mcp_proxy_adapter/examples/generate_test_configs.py,sha256=NLhPrA9AfPlQ0WCbOJ1B_V9OC445tanKTmq7aAWKULU,13672
92
+ mcp_proxy_adapter/examples/proxy_registration_example.py,sha256=g59_QG2D1CCqhIXEvgy2XmgXI3toLmLyH7hL3uHZwC8,12647
93
+ mcp_proxy_adapter/examples/run_example.py,sha256=o8rcy9Xo0UuZG4MpKdex3pFWYdtAi6uW8dEBQE6Yzbw,2539
94
+ mcp_proxy_adapter/examples/run_full_test_suite.py,sha256=7Z6qDOvbndGPue1P9v-GcYZxy_XPqoC9voJ7tR8eKQ8,12428
95
+ mcp_proxy_adapter/examples/run_proxy_server.py,sha256=vkEjqREcOSw2elH_VOBLa0cFjL8gCZp9nkRa8YLsndI,5119
96
+ mcp_proxy_adapter/examples/run_security_tests.py,sha256=BFeafoRXOhorJ8ScjjnlmPdRaCG8AaPAxb-PRnSGJTM,22639
97
+ mcp_proxy_adapter/examples/run_security_tests_fixed.py,sha256=fNQsbALf9548xJ0OGPKYx5Crzg1GbcL8CSh1x_oKu_A,10540
98
+ mcp_proxy_adapter/examples/security_test_client.py,sha256=0j0-RGg9kppt_IAuYeT8cbXr3N5gqBdzEyPd3RW0bs8,35558
99
+ mcp_proxy_adapter/examples/setup_test_environment.py,sha256=fAfz1U7qERY-Z9ly15Wld8Zci-5_e9zSrvYJ56Rjowo,11839
100
+ mcp_proxy_adapter/examples/test_config.py,sha256=1X9X8lNlWOcM1ZbIzteeMvLdgxnJEK_ev1BYTZiA9ws,6451
101
+ mcp_proxy_adapter/examples/test_config_generator.py,sha256=SBKL0bv-kUwUUbwrFVbxuA_6pDvK2573Jxm9wPiyI8s,3927
102
+ mcp_proxy_adapter/examples/test_examples.py,sha256=KH095FFEQDMKYZglclr5qy3cW__t3H8VX1l8dvCkQos,12132
103
+ mcp_proxy_adapter/examples/universal_client.py,sha256=IIKGRa0__KoWVla3VnVl-RjkkG_nPpM8vglPm70pV9c,26948
104
+ mcp_proxy_adapter/examples/basic_framework/__init__.py,sha256=4aYD--R6hy9n9CUxj7Osb9HcdVUMJ6_cfpu4ujkbCwI,345
105
+ mcp_proxy_adapter/examples/basic_framework/main.py,sha256=cDmqeUN1lDBBwuwLjmnP3qIyofCZ3Jr5Ct7Im-qCsUU,1728
106
+ mcp_proxy_adapter/examples/basic_framework/commands/__init__.py,sha256=_VQNLUEdsxUG-4yt9BZI_vtOxHAdGG0OUSsP6Wj-Vz4,76
107
+ mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py,sha256=IE_EIXMnkdXuakZn7wLD9kBFyfDF5lYi56ejgiBeb-A,70
108
+ mcp_proxy_adapter/examples/commands/__init__.py,sha256=46FZSOABSeKPffw91JqIWL_UQD_RLL3nAR-ufgb2hr8,169
109
+ mcp_proxy_adapter/examples/examples/basic_framework/__init__.py,sha256=4aYD--R6hy9n9CUxj7Osb9HcdVUMJ6_cfpu4ujkbCwI,345
110
+ mcp_proxy_adapter/examples/examples/basic_framework/main.py,sha256=cDmqeUN1lDBBwuwLjmnP3qIyofCZ3Jr5Ct7Im-qCsUU,1728
111
+ mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py,sha256=_VQNLUEdsxUG-4yt9BZI_vtOxHAdGG0OUSsP6Wj-Vz4,76
112
+ mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py,sha256=IE_EIXMnkdXuakZn7wLD9kBFyfDF5lYi56ejgiBeb-A,70
113
+ mcp_proxy_adapter/examples/examples/full_application/__init__.py,sha256=AEqN_gEBzj-swBtTOvRUWqKSdXqJVk1aUtfPghVL-2o,319
114
+ mcp_proxy_adapter/examples/examples/full_application/main.py,sha256=h2d90G6XMJFbJpo2ht7M1IqITZ9nZPi9QtH6ETeE9DI,7791
115
+ mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py,sha256=-cpb0nIjzp6OltFHoZqrtFvb4wJf1dgT4WvQ2dcY6Bo,6045
116
+ mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py,sha256=yQHxVSFkAyFLUOdk42QOebUODPlQV9IbydPgF3UKsGM,217
117
+ mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py,sha256=u9_XOkoHkiFC-tn9B-yGUXfQi9OL0EDxlVVKSERI1wA,3099
118
+ mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py,sha256=fRWtegpUUVt4wWOz3yE3spMG4h1DM_xbSxg_WqlnbF0,3491
119
+ mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py,sha256=ORG4cL8cSXEMmZ0CEPz75OVuwg54pdDm2GIBpP4dtcs,200
120
+ mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py,sha256=TYXuHI-KW_mH5r8mSKgNMJCr3moeEKrqC4Eex0U298k,3457
121
+ mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py,sha256=IaskSrckZS6bE3aGxSBL8aTj-iJTSI2ysfsFjhjncyM,2975
122
+ mcp_proxy_adapter/examples/full_application/__init__.py,sha256=AEqN_gEBzj-swBtTOvRUWqKSdXqJVk1aUtfPghVL-2o,319
123
+ mcp_proxy_adapter/examples/full_application/main.py,sha256=h2d90G6XMJFbJpo2ht7M1IqITZ9nZPi9QtH6ETeE9DI,7791
124
+ mcp_proxy_adapter/examples/full_application/proxy_endpoints.py,sha256=-cpb0nIjzp6OltFHoZqrtFvb4wJf1dgT4WvQ2dcY6Bo,6045
125
+ mcp_proxy_adapter/examples/full_application/commands/__init__.py,sha256=yQHxVSFkAyFLUOdk42QOebUODPlQV9IbydPgF3UKsGM,217
126
+ mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py,sha256=u9_XOkoHkiFC-tn9B-yGUXfQi9OL0EDxlVVKSERI1wA,3099
127
+ mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py,sha256=fRWtegpUUVt4wWOz3yE3spMG4h1DM_xbSxg_WqlnbF0,3491
128
+ mcp_proxy_adapter/examples/full_application/hooks/__init__.py,sha256=ORG4cL8cSXEMmZ0CEPz75OVuwg54pdDm2GIBpP4dtcs,200
129
+ mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py,sha256=TYXuHI-KW_mH5r8mSKgNMJCr3moeEKrqC4Eex0U298k,3457
130
+ mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py,sha256=IaskSrckZS6bE3aGxSBL8aTj-iJTSI2ysfsFjhjncyM,2975
131
+ mcp_proxy_adapter/examples/scripts/config_generator.py,sha256=4qruYxQ2kGLVOukLX2JOW5kslJ06RhkNqTobAgh4rfw,32801
132
+ mcp_proxy_adapter/examples/scripts/create_certificates_simple.py,sha256=xkIvUYl6hbKlWImQmenG0k_CvIsOsc9ZHICiKY3rtI8,26380
133
+ mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py,sha256=J0qHm_BMY8RYqfuwf7V7xKsHcsRJx8E7x-8JxmW5sPw,15988
134
+ mcp_proxy_adapter/utils/config_generator.py,sha256=2dxwBh9k_nUw9kgytZso5TNOQpBqd3c-RpKSTLoHlLE,46465
135
+ mcp_proxy_adapter-6.0.1.dist-info/licenses/LICENSE,sha256=6KdtUcTwmTRbJrAmYjVn7e6S-V42ubeDJ-AiVEzZ510,1075
136
+ mcp_proxy_adapter-6.0.1.dist-info/METADATA,sha256=UYIC4jHUJrNCj-7FlIHqekZvym3C5njJhaPp8XesdXA,22347
137
+ mcp_proxy_adapter-6.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
138
+ mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt,sha256=J3eV6ID0lt_VSp4lIdIgBFTqLCThgObNNxRCbyfiMHw,70
139
+ mcp_proxy_adapter-6.0.1.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
140
+ mcp_proxy_adapter-6.0.1.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mcp-proxy-adapter = mcp_proxy_adapter.__main__:main
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023-2024 Vasiliy VZ
3
+ Copyright (c) 2024 Vasiliy Zdanovskiy
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
@@ -1,146 +0,0 @@
1
- """
2
- Middleware for authentication.
3
- """
4
-
5
- import json
6
- from typing import Dict, List, Optional, Callable, Awaitable
7
-
8
- from fastapi import Request, Response
9
- from starlette.responses import JSONResponse
10
-
11
- from mcp_proxy_adapter.core.logging import logger
12
- from .base import BaseMiddleware
13
-
14
- class AuthMiddleware(BaseMiddleware):
15
- """
16
- Middleware for authenticating requests.
17
- """
18
-
19
- def __init__(self, app, api_keys: Dict[str, str] = None, public_paths: List[str] = None, auth_enabled: bool = True):
20
- """
21
- Initializes middleware for authentication.
22
-
23
- Args:
24
- app: FastAPI application
25
- api_keys: Dictionary with API keys (key: username)
26
- public_paths: List of paths accessible without authentication
27
- auth_enabled: Flag to enable/disable authentication
28
- """
29
- super().__init__(app)
30
- self.api_keys = api_keys or {}
31
- self.public_paths = public_paths or [
32
- "/docs",
33
- "/redoc",
34
- "/openapi.json",
35
- "/health"
36
- ]
37
- self.auth_enabled = auth_enabled
38
-
39
- async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
40
- """
41
- Processes request and checks authentication.
42
-
43
- Args:
44
- request: Request.
45
- call_next: Next handler.
46
-
47
- Returns:
48
- Response.
49
- """
50
- # Check if authentication is disabled
51
- if not self.auth_enabled:
52
- logger.debug("Authentication is disabled, skipping authentication check")
53
- return await call_next(request)
54
-
55
- # Check if path is public
56
- path = request.url.path
57
- if self._is_public_path(path):
58
- # If path is public, skip authentication
59
- return await call_next(request)
60
-
61
- # Check for API key in header
62
- api_key = request.headers.get("X-API-Key")
63
-
64
- if not api_key:
65
- # Check for API key in query parameters
66
- api_key = request.query_params.get("api_key")
67
-
68
- if not api_key and request.method in ["POST", "PUT", "PATCH"]:
69
- # Check for API key in JSON-RPC request body
70
- try:
71
- body = await request.body()
72
- if body:
73
- try:
74
- body_json = json.loads(body.decode("utf-8"))
75
- # Look for API key in params of JSON-RPC object
76
- if isinstance(body_json, dict) and "params" in body_json:
77
- api_key = body_json.get("params", {}).get("api_key")
78
- except json.JSONDecodeError:
79
- pass
80
- except Exception:
81
- pass
82
-
83
- # If API key not found, return error
84
- if not api_key:
85
- logger.warning(f"Authentication failed: API key not provided | Path: {path}")
86
- return self._create_error_response("API key not provided", 401)
87
-
88
- # Check if API key is valid
89
- username = self._validate_api_key(api_key)
90
- if not username:
91
- logger.warning(f"Authentication failed: Invalid API key | Path: {path}")
92
- return self._create_error_response("Invalid API key", 401)
93
-
94
- # If API key is valid, save user information in request state
95
- request.state.username = username
96
- logger.info(f"Authentication successful: {username} | Path: {path}")
97
-
98
- # Call the next middleware or main handler
99
- return await call_next(request)
100
-
101
- def _is_public_path(self, path: str) -> bool:
102
- """
103
- Checks if the path is public.
104
-
105
- Args:
106
- path: Path to check.
107
-
108
- Returns:
109
- True if path is public, False otherwise.
110
- """
111
- return any(path.startswith(public_path) for public_path in self.public_paths)
112
-
113
- def _validate_api_key(self, api_key: str) -> Optional[str]:
114
- """
115
- Validates API key.
116
-
117
- Args:
118
- api_key: API key to validate.
119
-
120
- Returns:
121
- Username if API key is valid, otherwise None.
122
- """
123
- return self.api_keys.get(api_key)
124
-
125
- def _create_error_response(self, message: str, status_code: int) -> Response:
126
- """
127
- Creates error response in JSON-RPC format.
128
-
129
- Args:
130
- message: Error message.
131
- status_code: HTTP status code.
132
-
133
- Returns:
134
- JSON response with error.
135
- """
136
- return JSONResponse(
137
- status_code=status_code,
138
- content={
139
- "jsonrpc": "2.0",
140
- "error": {
141
- "code": -32000,
142
- "message": message
143
- },
144
- "id": None
145
- }
146
- )
@@ -1,235 +0,0 @@
1
- """
2
- Auth Middleware Adapter for backward compatibility.
3
-
4
- This module provides an adapter that maintains the same interface as AuthMiddleware
5
- while using the new SecurityMiddleware internally.
6
- """
7
-
8
- import json
9
- from typing import Dict, List, Optional, Callable, Awaitable
10
-
11
- from fastapi import Request, Response
12
- from starlette.responses import JSONResponse
13
-
14
- from mcp_proxy_adapter.core.logging import logger
15
- from .base import BaseMiddleware
16
- from .security import SecurityMiddleware
17
-
18
-
19
- class AuthMiddlewareAdapter(BaseMiddleware):
20
- """
21
- Adapter for AuthMiddleware that uses SecurityMiddleware internally.
22
-
23
- Maintains the same interface as the original AuthMiddleware for backward compatibility.
24
- """
25
-
26
- def __init__(self, app, api_keys: Dict[str, str] = None,
27
- public_paths: List[str] = None, auth_enabled: bool = True):
28
- """
29
- Initialize auth middleware adapter.
30
-
31
- Args:
32
- app: FastAPI application
33
- api_keys: Dictionary with API keys (key: username)
34
- public_paths: List of paths accessible without authentication
35
- auth_enabled: Flag to enable/disable authentication
36
- """
37
- super().__init__(app)
38
-
39
- # Store original parameters for backward compatibility
40
- self.api_keys = api_keys or {}
41
- self.public_paths = public_paths or [
42
- "/docs",
43
- "/redoc",
44
- "/openapi.json",
45
- "/health"
46
- ]
47
- self.auth_enabled = auth_enabled
48
-
49
- # Create internal security middleware
50
- self.security_middleware = self._create_security_middleware()
51
-
52
- logger.info(f"AuthMiddlewareAdapter initialized: auth_enabled={auth_enabled}, "
53
- f"api_keys_count={len(self.api_keys)}, public_paths_count={len(self.public_paths)}")
54
-
55
- def _create_security_middleware(self) -> SecurityMiddleware:
56
- """
57
- Create internal SecurityMiddleware with AuthMiddleware configuration.
58
-
59
- Returns:
60
- SecurityMiddleware instance
61
- """
62
- # Convert AuthMiddleware config to SecurityMiddleware config
63
- security_config = {
64
- "security": {
65
- "enabled": self.auth_enabled,
66
- "auth": {
67
- "enabled": self.auth_enabled,
68
- "methods": ["api_key"],
69
- "api_keys": self.api_keys
70
- },
71
- "ssl": {
72
- "enabled": False
73
- },
74
- "permissions": {
75
- "enabled": False
76
- },
77
- "rate_limit": {
78
- "enabled": False
79
- },
80
- "public_paths": self.public_paths
81
- }
82
- }
83
-
84
- return SecurityMiddleware(self.app, security_config)
85
-
86
- async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
87
- """
88
- Process request using internal SecurityMiddleware with legacy API key handling.
89
-
90
- Args:
91
- request: Request object
92
- call_next: Next handler
93
-
94
- Returns:
95
- Response object
96
- """
97
- # Check if authentication is disabled
98
- if not self.auth_enabled:
99
- logger.debug("Authentication is disabled, skipping authentication check")
100
- return await call_next(request)
101
-
102
- # Check if path is public
103
- path = request.url.path
104
- if self._is_public_path(path):
105
- return await call_next(request)
106
-
107
- # Extract API key from various sources (legacy compatibility)
108
- api_key = self._extract_api_key(request)
109
-
110
- # Check for API key in JSON-RPC request body if not found in headers/query
111
- if not api_key and request.method in ["POST", "PUT", "PATCH"]:
112
- try:
113
- body = await request.body()
114
- if body:
115
- try:
116
- body_json = json.loads(body.decode("utf-8"))
117
- # Look for API key in params of JSON-RPC object
118
- if isinstance(body_json, dict) and "params" in body_json:
119
- api_key = body_json.get("params", {}).get("api_key")
120
- except json.JSONDecodeError:
121
- pass
122
- except Exception:
123
- pass
124
-
125
- if api_key:
126
- # Validate API key
127
- username = self._validate_api_key(api_key)
128
- if username:
129
- # Store username in request state for backward compatibility
130
- request.state.username = username
131
- logger.debug(f"API key authentication successful for {username}")
132
- return await call_next(request)
133
- else:
134
- logger.warning(f"Invalid API key provided | Path: {path}")
135
- return self._create_error_response("Invalid API key", 401)
136
- else:
137
- logger.warning(f"API key not provided | Path: {path}")
138
- return self._create_error_response("API key not provided", 401)
139
-
140
- def _extract_api_key(self, request: Request) -> Optional[str]:
141
- """
142
- Extract API key from request (legacy compatibility).
143
-
144
- Args:
145
- request: Request object
146
-
147
- Returns:
148
- API key or None
149
- """
150
- # Check for API key in header
151
- api_key = request.headers.get("X-API-Key")
152
-
153
- if not api_key:
154
- # Check for API key in query parameters
155
- api_key = request.query_params.get("api_key")
156
-
157
- # Note: Body extraction is handled in dispatch method
158
- # This method only handles headers and query parameters
159
-
160
- return api_key
161
-
162
- def _is_public_path(self, path: str) -> bool:
163
- """
164
- Check if the path is public (doesn't require authentication).
165
-
166
- Args:
167
- path: Request path
168
-
169
- Returns:
170
- True if path is public, False otherwise
171
- """
172
- return any(path.startswith(public_path) for public_path in self.public_paths)
173
-
174
- def _validate_api_key(self, api_key: str) -> Optional[str]:
175
- """
176
- Validate API key and return username.
177
-
178
- Args:
179
- api_key: API key to validate
180
-
181
- Returns:
182
- Username if valid, None otherwise
183
- """
184
- return self.api_keys.get(api_key)
185
-
186
- def _create_error_response(self, message: str, status_code: int) -> JSONResponse:
187
- """
188
- Create error response in AuthMiddleware format.
189
-
190
- Args:
191
- message: Error message
192
- status_code: HTTP status code
193
-
194
- Returns:
195
- JSONResponse with error
196
- """
197
- return JSONResponse(
198
- status_code=status_code,
199
- content={
200
- "jsonrpc": "2.0",
201
- "error": {
202
- "code": -32000 if status_code == 401 else -32603,
203
- "message": message,
204
- "data": {
205
- "auth_type": "api_key",
206
- "status_code": status_code
207
- }
208
- },
209
- "id": None
210
- }
211
- )
212
-
213
- def get_username(self, request: Request) -> Optional[str]:
214
- """
215
- Get username from request state (backward compatibility).
216
-
217
- Args:
218
- request: Request object
219
-
220
- Returns:
221
- Username or None
222
- """
223
- return getattr(request.state, 'username', None)
224
-
225
- def is_authenticated(self, request: Request) -> bool:
226
- """
227
- Check if request is authenticated (backward compatibility).
228
-
229
- Args:
230
- request: Request object
231
-
232
- Returns:
233
- True if authenticated, False otherwise
234
- """
235
- return hasattr(request.state, 'username') and request.state.username is not None