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
@@ -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
- }