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,566 +0,0 @@
1
- """
2
- Advanced Hooks Example
3
-
4
- This module demonstrates advanced hook capabilities:
5
- 1. Data transformation hooks - modify input data before command execution and format output after
6
- 2. Interception hooks - completely bypass command execution based on conditions
7
- """
8
-
9
- import time
10
- import logging
11
- from typing import Dict, Any
12
- from datetime import datetime
13
-
14
- from mcp_proxy_adapter.commands.hooks import hooks
15
- from mcp_proxy_adapter.commands.result import CommandResult
16
- from mcp_proxy_adapter.commands.hooks import HookContext
17
- from mcp_proxy_adapter.commands.hooks import HookType
18
- # Import will be done locally when needed to avoid circular imports
19
-
20
-
21
- # Setup logging for advanced hooks
22
- logger = logging.getLogger("mcp_proxy_adapter.examples.advanced_hooks")
23
-
24
-
25
- def data_transform_before_hook(context: HookContext) -> None:
26
- """
27
- Before hook for data_transform command - modifies input data.
28
-
29
- Args:
30
- context: Hook context with command information
31
- """
32
- logger.info(f"🔄 Data transform before hook: {context}")
33
-
34
- # Get original data
35
- original_data = context.params.get("data", {})
36
-
37
- # Transform data before command execution
38
- transformed_data = {}
39
- for key, value in original_data.items():
40
- if isinstance(value, str):
41
- # Add prefix and suffix to string values
42
- transformed_data[f"pre_{key}_post"] = f"ENHANCED_{value}_PROCESSED"
43
- elif isinstance(value, (int, float)):
44
- # Multiply numeric values by 2
45
- transformed_data[f"doubled_{key}"] = value * 2
46
- else:
47
- # Keep other types as is
48
- transformed_data[key] = value
49
-
50
- # Add metadata
51
- transformed_data["_hook_modified"] = True
52
- transformed_data["_modification_time"] = datetime.now().isoformat()
53
-
54
- # Replace original data with transformed data
55
- context.params["data"] = transformed_data
56
- context.params["data_modified"] = True
57
-
58
- logger.info(f"📊 Original data: {original_data}")
59
- logger.info(f"🔄 Transformed data: {transformed_data}")
60
-
61
-
62
- def data_transform_after_hook(context: HookContext) -> None:
63
- """
64
- After hook for data_transform command - formats output data.
65
-
66
- Args:
67
- context: Hook context with command information
68
- """
69
- logger.info(f"🔄 Data transform after hook: {context}")
70
-
71
- if context.result and hasattr(context.result, 'transformed_data'):
72
- # Get the transformed data from command result
73
- transformed_data = context.result.transformed_data
74
-
75
- # Apply additional formatting
76
- formatted_data = {}
77
- for key, value in transformed_data.items():
78
- if isinstance(value, str):
79
- # Add formatting to string values
80
- formatted_data[f"formatted_{key}"] = f"✨ {value} ✨"
81
- else:
82
- formatted_data[key] = value
83
-
84
- # Add formatting metadata
85
- formatted_data["_formatted_by_hook"] = True
86
- formatted_data["_formatting_time"] = datetime.now().isoformat()
87
-
88
- # Update the result with formatted data
89
- context.result.transformed_data = formatted_data
90
-
91
- logger.info(f"✨ Formatted data: {formatted_data}")
92
-
93
-
94
- def intercept_before_hook(context: HookContext) -> None:
95
- """
96
- Before hook for intercept command - can completely bypass execution.
97
-
98
- Args:
99
- context: Hook context with command information
100
- """
101
- logger.info(f"🚫 Intercept before hook: {context}")
102
-
103
- # Check bypass flag
104
- bypass_flag = context.params.get("bypass_flag", 1)
105
-
106
- if bypass_flag == 0:
107
- # Completely bypass command execution
108
- logger.info(f"🚫 Intercepting command execution - bypass_flag = 0")
109
-
110
- # Create a mock result without calling the actual command
111
- from .intercept_command import InterceptResult
112
-
113
- mock_result = InterceptResult(
114
- message="Command intercepted by hook - not executed",
115
- executed=False,
116
- intercept_reason="bypass_flag = 0",
117
- hook_data={
118
- "intercepted_by": "intercept_before_hook",
119
- "interception_time": datetime.now().isoformat(),
120
- "bypass_flag": bypass_flag
121
- }
122
- )
123
-
124
- # Set the result and disable standard processing
125
- context.result = mock_result
126
- context.standard_processing = False
127
-
128
- logger.info(f"🚫 Command execution bypassed, result: {mock_result}")
129
- else:
130
- logger.info(f"✅ Command execution allowed - bypass_flag = {bypass_flag}")
131
- context.params["hook_processed"] = True
132
-
133
-
134
- def intercept_after_hook(context: HookContext) -> None:
135
- """
136
- After hook for intercept command.
137
-
138
- Args:
139
- context: Hook context with command information
140
- """
141
- if context.standard_processing:
142
- logger.info(f"✅ Intercept command executed normally")
143
- else:
144
- logger.info(f"🚫 Intercept command was intercepted by hook")
145
-
146
- # Add execution metadata
147
- if context.result and hasattr(context.result, 'hook_data'):
148
- context.result.hook_data["after_hook_processed"] = True
149
- context.result.hook_data["after_hook_time"] = datetime.now().isoformat()
150
-
151
-
152
- def conditional_transform_hook(context: HookContext) -> None:
153
- """
154
- Conditional transformation hook - applies different transformations based on data.
155
-
156
- Args:
157
- context: Hook context with command information
158
- """
159
- if context.hook_type == HookType.BEFORE_EXECUTION:
160
- logger.info(f"🎯 Conditional transform before hook: {context.command_name}")
161
-
162
- # Check if this is a data_transform command
163
- if context.command_name == "data_transform":
164
- data = context.params.get("data", {})
165
- transform_type = context.params.get("transform_type", "default")
166
-
167
- # Apply conditional transformation based on data content
168
- if "special" in str(data).lower():
169
- logger.info(f"🎯 Special data detected - applying enhanced transformation")
170
- context.params["transform_type"] = "uppercase"
171
- context.params["_special_enhancement"] = True
172
- elif "test" in str(data).lower():
173
- logger.info(f"🎯 Test data detected - applying test transformation")
174
- context.params["transform_type"] = "reverse"
175
- context.params["_test_mode"] = True
176
-
177
- elif context.hook_type == HookType.AFTER_EXECUTION:
178
- logger.info(f"🎯 Conditional transform after hook: {context.command_name}")
179
-
180
- # Add conditional metadata to result
181
- if context.result and hasattr(context.result, 'processing_info'):
182
- context.result.processing_info["conditional_processed"] = True
183
- context.result.processing_info["conditional_time"] = datetime.now().isoformat()
184
-
185
-
186
- def smart_intercept_hook(context: HookContext) -> None:
187
- """
188
- Smart interception hook - intercepts based on multiple conditions.
189
-
190
- Args:
191
- context: Hook context with command information
192
- """
193
- if context.hook_type == HookType.BEFORE_EXECUTION:
194
- logger.info(f"🧠 Smart intercept before hook: {context.command_name}")
195
-
196
- # Check multiple conditions for interception
197
- action = context.params.get("action", "")
198
- bypass_flag = context.params.get("bypass_flag", 1)
199
-
200
- # Intercept if action is "blocked" or bypass_flag is 0
201
- if action == "blocked" or bypass_flag == 0:
202
- logger.info(f"🧠 Smart intercept: action='{action}', bypass_flag={bypass_flag}")
203
-
204
- # Create intercepted result
205
- from .intercept_command import InterceptResult
206
-
207
- intercept_reason = "blocked_action" if action == "blocked" else "bypass_flag_zero"
208
-
209
- mock_result = InterceptResult(
210
- message=f"Command intercepted by smart hook - reason: {intercept_reason}",
211
- executed=False,
212
- intercept_reason=intercept_reason,
213
- hook_data={
214
- "intercepted_by": "smart_intercept_hook",
215
- "interception_time": datetime.now().isoformat(),
216
- "smart_analysis": True
217
- }
218
- )
219
-
220
- # Set the result and disable standard processing
221
- context.result = mock_result
222
- context.standard_processing = False
223
-
224
- logger.info(f"✅ Smart interception completed")
225
-
226
-
227
- def register_advanced_hooks(hooks_manager) -> None:
228
- """
229
- Register advanced hooks with the hooks system.
230
-
231
- Args:
232
- hooks_manager: Hooks manager instance to register hooks with
233
- """
234
- logger.info("🔧 Registering advanced hooks...")
235
-
236
- # Register data transform hooks
237
- hooks_manager.register_before_hook("data_transform", data_transform_before_hook)
238
- hooks_manager.register_after_hook("data_transform", data_transform_after_hook)
239
-
240
- # Register intercept hooks
241
- hooks_manager.register_before_hook("intercept", intercept_before_hook)
242
- hooks_manager.register_after_hook("intercept", intercept_after_hook)
243
-
244
- # Register global hooks
245
- hooks_manager.register_global_before_hook(conditional_transform_hook)
246
- hooks_manager.register_global_before_hook(smart_intercept_hook)
247
- hooks_manager.register_global_after_hook(conditional_transform_hook)
248
-
249
- # Register system lifecycle hooks
250
- hooks_manager.register_before_init_hook(system_before_init_hook)
251
- hooks_manager.register_after_init_hook(system_after_init_hook)
252
-
253
- # Register command-specific hooks for all commands
254
- hooks_manager.register_before_hook("echo", echo_before_hook)
255
- hooks_manager.register_after_hook("echo", echo_after_hook)
256
-
257
- hooks_manager.register_before_hook("help", help_before_hook)
258
- hooks_manager.register_after_hook("help", help_after_hook)
259
-
260
- hooks_manager.register_before_hook("health", health_before_hook)
261
- hooks_manager.register_after_hook("health", health_after_hook)
262
-
263
- hooks_manager.register_before_hook("config", config_before_hook)
264
- hooks_manager.register_after_hook("config", config_after_hook)
265
-
266
- hooks_manager.register_before_hook("load", load_before_hook)
267
- hooks_manager.register_after_hook("load", load_after_hook)
268
-
269
- hooks_manager.register_before_hook("unload", unload_before_hook)
270
- hooks_manager.register_after_hook("unload", unload_after_hook)
271
-
272
- hooks_manager.register_before_hook("reload", reload_before_hook)
273
- hooks_manager.register_after_hook("reload", reload_after_hook)
274
-
275
- hooks_manager.register_before_hook("plugins", plugins_before_hook)
276
- hooks_manager.register_after_hook("plugins", plugins_after_hook)
277
-
278
- hooks_manager.register_before_hook("settings", settings_before_hook)
279
- hooks_manager.register_after_hook("settings", settings_after_hook)
280
-
281
- # Register custom commands hooks
282
- hooks_manager.register_before_hook("manual_echo", manual_echo_before_hook)
283
- hooks_manager.register_after_hook("manual_echo", manual_echo_after_hook)
284
-
285
- hooks_manager.register_before_hook("auto_echo", auto_echo_before_hook)
286
- hooks_manager.register_after_hook("auto_echo", auto_echo_after_hook)
287
-
288
- hooks_manager.register_before_hook("auto_info", auto_info_before_hook)
289
- hooks_manager.register_after_hook("auto_info", auto_info_after_hook)
290
-
291
- logger.info("✅ Advanced hooks registered successfully")
292
-
293
-
294
- # ============================================================================
295
- # SYSTEM LIFECYCLE HOOKS
296
- # ============================================================================
297
-
298
- def system_before_init_hook(registry) -> None:
299
- """
300
- Before system initialization hook.
301
-
302
- Args:
303
- registry: Command registry instance
304
- """
305
- logger.info("🚀 System before init hook: Preparing system initialization")
306
-
307
- # Add initialization metadata
308
- registry.metadata["init_start_time"] = datetime.now().isoformat()
309
- registry.metadata["init_hooks_processed"] = True
310
-
311
- logger.info("✅ System initialization preparation completed")
312
-
313
-
314
- def system_after_init_hook(registry) -> None:
315
- """
316
- After system initialization hook.
317
-
318
- Args:
319
- registry: Command registry instance
320
- """
321
- logger.info("🎉 System after init hook: System initialization completed")
322
-
323
- # Add completion metadata
324
- registry.metadata["init_end_time"] = datetime.now().isoformat()
325
- registry.metadata["total_commands"] = len(registry.get_all_commands())
326
-
327
- logger.info(f"✅ System initialization completed with {registry.metadata['total_commands']} commands")
328
-
329
-
330
- # ============================================================================
331
- # BUILT-IN COMMAND HOOKS
332
- # ============================================================================
333
-
334
- def echo_before_hook(context: HookContext) -> None:
335
- """Before hook for echo command."""
336
- logger.info(f"📢 Echo before hook: {context.command_name}")
337
-
338
- # Add timestamp to message
339
- if context.params and "message" in context.params:
340
- original_message = context.params["message"]
341
- context.params["message"] = f"[{datetime.now().strftime('%H:%M:%S')}] {original_message}"
342
- context.params["_timestamp_added"] = True
343
-
344
- context.metadata["echo_processed"] = True
345
-
346
-
347
- def echo_after_hook(context: HookContext) -> None:
348
- """After hook for echo command."""
349
- logger.info(f"📢 Echo after hook: {context.command_name}")
350
-
351
- if context.result and hasattr(context.result, 'message'):
352
- context.result.message = f"ECHO: {context.result.message}"
353
- context.metadata["echo_formatted"] = True
354
-
355
-
356
- def help_before_hook(context: HookContext) -> None:
357
- """Before hook for help command."""
358
- logger.info(f"❓ Help before hook: {context.command_name}")
359
-
360
- # Add help metadata
361
- context.metadata["help_requested"] = True
362
- context.metadata["help_time"] = datetime.now().isoformat()
363
-
364
-
365
- def help_after_hook(context: HookContext) -> None:
366
- """After hook for help command."""
367
- logger.info(f"❓ Help after hook: {context.command_name}")
368
-
369
- if context.result and hasattr(context.result, 'commands_info'):
370
- # Add hook information to help
371
- context.result.commands_info["hooks_available"] = True
372
- context.result.commands_info["hook_count"] = 15 # Total number of hooks
373
-
374
-
375
- def health_before_hook(context: HookContext) -> None:
376
- """Before hook for health command."""
377
- logger.info(f"🏥 Health before hook: {context.command_name}")
378
-
379
- # Add health check metadata
380
- context.metadata["health_check_start"] = datetime.now().isoformat()
381
-
382
-
383
- def health_after_hook(context: HookContext) -> None:
384
- """After hook for health command."""
385
- logger.info(f"🏥 Health after hook: {context.command_name}")
386
-
387
- if context.result and hasattr(context.result, 'status'):
388
- # Add hook health status
389
- context.result.status["hooks_healthy"] = True
390
- context.result.status["hook_count"] = 15
391
-
392
-
393
- def config_before_hook(context: HookContext) -> None:
394
- """Before hook for config command."""
395
- logger.info(f"⚙️ Config before hook: {context.command_name}")
396
-
397
- # Add config operation metadata
398
- context.metadata["config_operation"] = context.params.get("operation", "unknown")
399
- context.metadata["config_time"] = datetime.now().isoformat()
400
-
401
-
402
- def config_after_hook(context: HookContext) -> None:
403
- """After hook for config command."""
404
- logger.info(f"⚙️ Config after hook: {context.command_name}")
405
-
406
- if context.result and hasattr(context.result, 'config'):
407
- # Add hook configuration
408
- context.result.config["hooks_enabled"] = True
409
- context.result.config["hook_system_version"] = "1.0.0"
410
-
411
-
412
- def load_before_hook(context: HookContext) -> None:
413
- """Before hook for load command."""
414
- logger.info(f"📦 Load before hook: {context.command_name}")
415
-
416
- # Add load metadata
417
- context.metadata["load_source"] = context.params.get("source", "unknown")
418
- context.metadata["load_time"] = datetime.now().isoformat()
419
-
420
-
421
- def load_after_hook(context: HookContext) -> None:
422
- """After hook for load command."""
423
- logger.info(f"📦 Load after hook: {context.command_name}")
424
-
425
- if context.result and hasattr(context.result, 'loaded_commands'):
426
- # Add hook information to loaded commands
427
- context.result.loaded_commands["_hooks_loaded"] = True
428
-
429
-
430
- def unload_before_hook(context: HookContext) -> None:
431
- """Before hook for unload command."""
432
- logger.info(f"🗑️ Unload before hook: {context.command_name}")
433
-
434
- # Add unload metadata
435
- context.metadata["unload_command"] = context.params.get("command_name", "unknown")
436
- context.metadata["unload_time"] = datetime.now().isoformat()
437
-
438
-
439
- def unload_after_hook(context: HookContext) -> None:
440
- """After hook for unload command."""
441
- logger.info(f"🗑️ Unload after hook: {context.command_name}")
442
-
443
- if context.result and hasattr(context.result, 'unloaded_commands'):
444
- # Add hook information to unloaded commands
445
- context.result.unloaded_commands["_hooks_cleaned"] = True
446
-
447
-
448
- def reload_before_hook(context: HookContext) -> None:
449
- """Before hook for reload command."""
450
- logger.info(f"🔄 Reload before hook: {context.command_name}")
451
-
452
- # Add reload metadata
453
- context.metadata["reload_components"] = context.params.get("components", [])
454
- context.metadata["reload_time"] = datetime.now().isoformat()
455
-
456
-
457
- def reload_after_hook(context: HookContext) -> None:
458
- """After hook for reload command."""
459
- logger.info(f"🔄 Reload after hook: {context.command_name}")
460
-
461
- if context.result and hasattr(context.result, 'reloaded_components'):
462
- # Add hook information to reloaded components
463
- context.result.reloaded_components["_hooks_reloaded"] = True
464
-
465
-
466
- def plugins_before_hook(context: HookContext) -> None:
467
- """Before hook for plugins command."""
468
- logger.info(f"🔌 Plugins before hook: {context.command_name}")
469
-
470
- # Add plugins metadata
471
- context.metadata["plugins_check_time"] = datetime.now().isoformat()
472
-
473
-
474
- def plugins_after_hook(context: HookContext) -> None:
475
- """After hook for plugins command."""
476
- logger.info(f"🔌 Plugins after hook: {context.command_name}")
477
-
478
- if context.result and hasattr(context.result, 'plugins'):
479
- # Add hook information to plugins
480
- context.result.plugins["_hooks_plugin"] = {
481
- "name": "Advanced Hooks System",
482
- "version": "1.0.0",
483
- "enabled": True
484
- }
485
-
486
-
487
- def settings_before_hook(context: HookContext) -> None:
488
- """Before hook for settings command."""
489
- logger.info(f"🔧 Settings before hook: {context.command_name}")
490
-
491
- # Add settings metadata
492
- context.metadata["settings_operation"] = context.params.get("operation", "unknown")
493
- context.metadata["settings_time"] = datetime.now().isoformat()
494
-
495
-
496
- def settings_after_hook(context: HookContext) -> None:
497
- """After hook for settings command."""
498
- logger.info(f"🔧 Settings after hook: {context.command_name}")
499
-
500
- if context.result and hasattr(context.result, 'settings'):
501
- # Add hook settings
502
- context.result.settings["hooks"] = {
503
- "enabled": True,
504
- "before_hooks": 15,
505
- "after_hooks": 15,
506
- "global_hooks": 3
507
- }
508
-
509
-
510
- # ============================================================================
511
- # CUSTOM COMMAND HOOKS
512
- # ============================================================================
513
-
514
- def manual_echo_before_hook(context: HookContext) -> None:
515
- """Before hook for manual echo command."""
516
- logger.info(f"📝 Manual echo before hook: {context.command_name}")
517
-
518
- # Add manual registration flag
519
- if context.params and "message" in context.params:
520
- context.params["_manually_registered"] = True
521
- context.params["_hook_processed"] = True
522
-
523
-
524
- def manual_echo_after_hook(context: HookContext) -> None:
525
- """After hook for manual echo command."""
526
- logger.info(f"📝 Manual echo after hook: {context.command_name}")
527
-
528
- if context.result and hasattr(context.result, 'message'):
529
- context.result.message = f"[MANUAL] {context.result.message}"
530
-
531
-
532
- def auto_echo_before_hook(context: HookContext) -> None:
533
- """Before hook for auto echo command."""
534
- logger.info(f"🤖 Auto echo before hook: {context.command_name}")
535
-
536
- # Add auto registration flag
537
- if context.params and "message" in context.params:
538
- context.params["_auto_registered"] = True
539
- context.params["_hook_processed"] = True
540
-
541
-
542
- def auto_echo_after_hook(context: HookContext) -> None:
543
- """After hook for auto echo command."""
544
- logger.info(f"🤖 Auto echo after hook: {context.command_name}")
545
-
546
- if context.result and hasattr(context.result, 'message'):
547
- context.result.message = f"[AUTO] {context.result.message}"
548
-
549
-
550
- def auto_info_before_hook(context: HookContext) -> None:
551
- """Before hook for auto info command."""
552
- logger.info(f"🤖 Auto info before hook: {context.command_name}")
553
-
554
- # Add auto registration flag
555
- if context.params and "topic" in context.params:
556
- context.params["_auto_registered"] = True
557
- context.params["_hook_processed"] = True
558
-
559
-
560
- def auto_info_after_hook(context: HookContext) -> None:
561
- """After hook for auto info command."""
562
- logger.info(f"🤖 Auto info after hook: {context.command_name}")
563
-
564
- if context.result and hasattr(context.result, 'info'):
565
- context.result.info["_auto_generated"] = True
566
- context.result.info["_hook_enhanced"] = True
@@ -1,6 +0,0 @@
1
- """
2
- Auto-registered commands package.
3
-
4
- Commands in this package will be automatically discovered and registered
5
- by the framework's auto-discovery mechanism.
6
- """
@@ -1,103 +0,0 @@
1
- """
2
- Auto-registered Echo Command
3
-
4
- This command will be automatically discovered and registered by the framework.
5
- """
6
-
7
- from typing import Dict, Any, Optional
8
- from mcp_proxy_adapter.commands.base import Command
9
- from mcp_proxy_adapter.commands.result import CommandResult
10
-
11
-
12
- class AutoEchoResult(CommandResult):
13
- """
14
- Result of the auto-registered echo command execution.
15
- """
16
-
17
- def __init__(self, message: str, auto_registered: bool = True):
18
- """
19
- Initialize auto echo command result.
20
-
21
- Args:
22
- message: Echoed message
23
- auto_registered: Flag indicating this was auto-registered
24
- """
25
- self.message = message
26
- self.auto_registered = auto_registered
27
-
28
- def to_dict(self) -> Dict[str, Any]:
29
- """
30
- Convert result to dictionary.
31
-
32
- Returns:
33
- Dict[str, Any]: Result as dictionary
34
- """
35
- return {
36
- "message": self.message,
37
- "auto_registered": self.auto_registered,
38
- "command_type": "auto_echo"
39
- }
40
-
41
- @classmethod
42
- def get_schema(cls) -> Dict[str, Any]:
43
- """
44
- Get JSON schema for the result.
45
-
46
- Returns:
47
- Dict[str, Any]: JSON schema
48
- """
49
- return {
50
- "type": "object",
51
- "properties": {
52
- "message": {"type": "string"},
53
- "auto_registered": {"type": "boolean"},
54
- "command_type": {"type": "string"}
55
- }
56
- }
57
-
58
-
59
- class AutoEchoCommand(Command):
60
- """
61
- Auto-registered echo command.
62
- """
63
-
64
- name = "auto_echo"
65
- result_class = AutoEchoResult
66
-
67
- async def execute(self, message: Optional[str] = None, **kwargs) -> AutoEchoResult:
68
- """
69
- Execute auto-registered echo command.
70
-
71
- Args:
72
- message: Message to echo
73
- **kwargs: Additional parameters
74
-
75
- Returns:
76
- AutoEchoResult: Auto echo command result
77
- """
78
- if message is None:
79
- message = "Hello from auto-registered command!"
80
-
81
- return AutoEchoResult(
82
- message=message,
83
- auto_registered=True
84
- )
85
-
86
- @classmethod
87
- def get_schema(cls) -> Dict[str, Any]:
88
- """
89
- Get JSON schema for command parameters.
90
-
91
- Returns:
92
- Dict[str, Any]: JSON schema
93
- """
94
- return {
95
- "type": "object",
96
- "properties": {
97
- "message": {
98
- "type": "string",
99
- "description": "Message to echo",
100
- "default": "Hello from auto-registered command!"
101
- }
102
- }
103
- }