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,103 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Script to get OpenAPI schema directly from the code.
4
- """
5
-
6
- import json
7
- import asyncio
8
- import sys
9
- import os
10
- from pathlib import Path
11
-
12
- # Add current directory to path for imports
13
- sys.path.insert(0, os.getcwd())
14
-
15
- from mcp_proxy_adapter.custom_openapi import CustomOpenAPIGenerator
16
- from mcp_proxy_adapter.commands.command_registry import registry
17
-
18
- async def main():
19
- """Generate and save OpenAPI schema."""
20
- try:
21
- # Initialize commands first
22
- print("🔄 Initializing commands...")
23
- result = await registry.reload_system()
24
- print(f"✅ Commands initialized: {result}")
25
-
26
- # Load custom commands manually
27
- print("🔄 Loading custom commands...")
28
- custom_commands = [
29
- "echo_command",
30
- "custom_help_command",
31
- "custom_health_command",
32
- "manual_echo_command"
33
- ]
34
-
35
- for cmd_name in custom_commands:
36
- try:
37
- # Import the command module
38
- module = __import__(cmd_name)
39
- print(f"✅ Loaded custom command: {cmd_name}")
40
-
41
- # Try to register the command if it has a command class
42
- if hasattr(module, 'EchoCommand'):
43
- registry.register_custom(module.EchoCommand())
44
- print(f"✅ Registered EchoCommand")
45
- elif hasattr(module, 'CustomHelpCommand'):
46
- registry.register_custom(module.CustomHelpCommand())
47
- print(f"✅ Registered CustomHelpCommand")
48
- elif hasattr(module, 'CustomHealthCommand'):
49
- registry.register_custom(module.CustomHealthCommand())
50
- print(f"✅ Registered CustomHealthCommand")
51
- elif hasattr(module, 'ManualEchoCommand'):
52
- registry.register_custom(module.ManualEchoCommand())
53
- print(f"✅ Registered ManualEchoCommand")
54
-
55
- except Exception as e:
56
- print(f"⚠️ Failed to load {cmd_name}: {e}")
57
-
58
- # Get commands after registration
59
- print("📋 Getting commands after registration...")
60
- commands = registry.get_all_commands()
61
- print(f" Total commands: {len(commands)}")
62
- print(f" Command names: {list(commands.keys())}")
63
-
64
- # Create generator
65
- generator = CustomOpenAPIGenerator()
66
-
67
- # Generate schema
68
- schema = generator.generate(
69
- title="Extended MCP Proxy Server",
70
- description="Advanced MCP Proxy Adapter server with custom commands and hooks",
71
- version="2.1.0"
72
- )
73
-
74
- # Save to file
75
- with open("generated_openapi.json", "w", encoding="utf-8") as f:
76
- json.dump(schema, f, indent=2, ensure_ascii=False)
77
-
78
- print("✅ OpenAPI schema generated successfully!")
79
- print(f"📄 Saved to: generated_openapi.json")
80
- print(f"📊 Schema size: {len(json.dumps(schema))} characters")
81
-
82
- # Show basic info
83
- print(f"\n📋 Schema info:")
84
- print(f" Title: {schema['info']['title']}")
85
- print(f" Version: {schema['info']['version']}")
86
-
87
- # Get commands info
88
- commands = registry.get_all_commands()
89
- print(f" Commands: {len(commands)}")
90
- print(f" Command names: {list(commands.keys())}")
91
-
92
- # Check CommandRequest enum
93
- command_enum = schema['components']['schemas'].get('CommandRequest', {}).get('properties', {}).get('command', {}).get('enum', [])
94
- print(f" Commands in schema: {len(command_enum)}")
95
- print(f" Schema commands: {command_enum}")
96
-
97
- except Exception as e:
98
- print(f"❌ Error generating schema: {e}")
99
- import traceback
100
- traceback.print_exc()
101
-
102
- if __name__ == "__main__":
103
- asyncio.run(main())
@@ -1,230 +0,0 @@
1
- """
2
- Custom Hooks Example
3
-
4
- This module demonstrates how to use hooks in the MCP Proxy Adapter framework.
5
- Hooks allow you to intercept command execution before and after processing.
6
- """
7
-
8
- import time
9
- import logging
10
- from typing import Dict, Any
11
- from datetime import datetime
12
-
13
- from mcp_proxy_adapter.commands.hooks import HookContext, HookType
14
-
15
-
16
- # Setup logging for hooks
17
- logger = logging.getLogger("mcp_proxy_adapter.examples.hooks")
18
-
19
-
20
- def echo_before_hook(context: HookContext) -> None:
21
- """
22
- Before hook for echo command.
23
-
24
- Args:
25
- context: Hook context with command information
26
- """
27
- logger.info(f"🔔 Echo command will be executed with params: {context.params}")
28
-
29
- # Add timestamp to params
30
- context.params["hook_timestamp"] = datetime.now().isoformat()
31
-
32
- # Log the message that will be echoed
33
- message = context.params.get("message", context.params.get("text", "Hello, World!"))
34
- logger.info(f"📢 Will echo message: '{message}'")
35
-
36
-
37
- def echo_after_hook(context: HookContext) -> None:
38
- """
39
- After hook for echo command.
40
-
41
- Args:
42
- context: Hook context with command information
43
- """
44
- logger.info(f"✅ Echo command completed successfully")
45
-
46
- # Log the result
47
- if context.result and hasattr(context.result, 'data'):
48
- echoed_message = context.result.data.get("message", "Unknown")
49
- timestamp = context.result.data.get("timestamp", "Unknown")
50
- logger.info(f"📤 Echoed: '{echoed_message}' at {timestamp}")
51
-
52
-
53
- def help_before_hook(context: HookContext) -> None:
54
- """
55
- Before hook for help command.
56
-
57
- Args:
58
- context: Hook context with command information
59
- """
60
- logger.info(f"🔔 Help command will be executed")
61
-
62
- # Add request tracking
63
- context.params["request_id"] = f"help_{int(time.time())}"
64
- context.params["hook_processed"] = True
65
-
66
- cmdname = context.params.get("cmdname")
67
- if cmdname:
68
- logger.info(f"📖 Will get help for command: {cmdname}")
69
- else:
70
- logger.info(f"📖 Will get help for all commands")
71
-
72
-
73
- def help_after_hook(context: HookContext) -> None:
74
- """
75
- After hook for help command.
76
-
77
- Args:
78
- context: Hook context with command information
79
- """
80
- logger.info(f"✅ Help command completed successfully")
81
-
82
- # Log the result summary
83
- if context.result and hasattr(context.result, 'to_dict'):
84
- result_dict = context.result.to_dict()
85
- total_commands = result_dict.get("total", 0)
86
- logger.info(f"📚 Help returned {total_commands} commands")
87
-
88
-
89
- def health_before_hook(context: HookContext) -> None:
90
- """
91
- Before hook for health command.
92
-
93
- Args:
94
- context: Hook context with command information
95
- """
96
- logger.info(f"🔔 Health command will be executed")
97
-
98
- # Add health check metadata
99
- context.params["health_check_id"] = f"health_{int(time.time())}"
100
- context.params["hook_enhanced"] = True
101
-
102
- logger.info(f"🏥 Starting enhanced health check")
103
-
104
-
105
- def health_after_hook(context: HookContext) -> None:
106
- """
107
- After hook for health command.
108
-
109
- Args:
110
- context: Hook context with command information
111
- """
112
- logger.info(f"✅ Health command completed successfully")
113
-
114
- # Log health status
115
- if context.result and hasattr(context.result, 'data'):
116
- status = context.result.data.get("status", "unknown")
117
- uptime = context.result.data.get("uptime", 0)
118
- logger.info(f"🏥 Health status: {status}, Uptime: {uptime:.2f}s")
119
-
120
-
121
- def global_before_hook(context: HookContext) -> None:
122
- """
123
- Global before hook for all commands.
124
-
125
- Args:
126
- context: Hook context with command information
127
- """
128
- logger.info(f"🌐 Global before hook: {context.command_name}")
129
-
130
- # Add global tracking
131
- context.params["global_hook_processed"] = True
132
- context.params["execution_start_time"] = time.time()
133
-
134
- logger.info(f"🚀 Starting execution of '{context.command_name}'")
135
-
136
-
137
- def global_after_hook(context: HookContext) -> None:
138
- """
139
- Global after hook for all commands.
140
-
141
- Args:
142
- context: Hook context with command information
143
- """
144
- start_time = context.params.get("execution_start_time", time.time())
145
- execution_time = time.time() - start_time
146
-
147
- logger.info(f"🌐 Global after hook: {context.command_name}")
148
- logger.info(f"⏱️ Execution time: {execution_time:.3f}s")
149
-
150
- # Log success/failure
151
- if context.result:
152
- logger.info(f"✅ Command '{context.command_name}' completed successfully")
153
- else:
154
- logger.warning(f"⚠️ Command '{context.command_name}' completed with issues")
155
-
156
-
157
- def performance_hook(context: HookContext) -> None:
158
- """
159
- Performance monitoring hook.
160
-
161
- Args:
162
- context: Hook context with command information
163
- """
164
- if context.hook_type == HookType.BEFORE_EXECUTION:
165
- # Store start time
166
- context.params["_performance_start"] = time.time()
167
- logger.debug(f"⏱️ Performance monitoring started for {context.command_name}")
168
-
169
- elif context.hook_type == HookType.AFTER_EXECUTION:
170
- # Calculate execution time
171
- start_time = context.params.get("_performance_start", time.time())
172
- execution_time = time.time() - start_time
173
-
174
- logger.info(f"📊 Performance: {context.command_name} took {execution_time:.3f}s")
175
-
176
- # Log slow commands
177
- if execution_time > 1.0:
178
- logger.warning(f"🐌 Slow command detected: {context.command_name} ({execution_time:.3f}s)")
179
-
180
-
181
- def security_hook(context: HookContext) -> None:
182
- """
183
- Security monitoring hook.
184
-
185
- Args:
186
- context: Hook context with command information
187
- """
188
- if context.hook_type == HookType.BEFORE_EXECUTION:
189
- # Check for sensitive data in params
190
- sensitive_keys = ["password", "token", "secret", "key"]
191
- found_sensitive = [key for key in context.params.keys() if any(s in key.lower() for s in sensitive_keys)]
192
-
193
- if found_sensitive:
194
- logger.warning(f"🔒 Security: Sensitive parameters detected in {context.command_name}: {found_sensitive}")
195
-
196
- # Add security metadata
197
- context.params["_security_checked"] = True
198
- logger.debug(f"🔒 Security check completed for {context.command_name}")
199
-
200
-
201
- def register_all_hooks(hooks_manager) -> None:
202
- """
203
- Register all hooks with the hooks manager.
204
-
205
- Args:
206
- hooks_manager: The hooks manager instance
207
- """
208
- logger.info("🔧 Registering custom hooks...")
209
-
210
- # Register command-specific hooks
211
- hooks_manager.register_before_hook("echo", echo_before_hook)
212
- hooks_manager.register_after_hook("echo", echo_after_hook)
213
-
214
- hooks_manager.register_before_hook("help", help_before_hook)
215
- hooks_manager.register_after_hook("help", help_after_hook)
216
-
217
- hooks_manager.register_before_hook("health", health_before_hook)
218
- hooks_manager.register_after_hook("health", health_after_hook)
219
-
220
- # Register global hooks
221
- hooks_manager.register_global_before_hook(global_before_hook)
222
- hooks_manager.register_global_after_hook(global_after_hook)
223
-
224
- # Register utility hooks
225
- hooks_manager.register_global_before_hook(performance_hook)
226
- hooks_manager.register_global_after_hook(performance_hook)
227
-
228
- hooks_manager.register_global_before_hook(security_hook)
229
-
230
- logger.info("✅ All hooks registered successfully")
@@ -1,123 +0,0 @@
1
- """
2
- Intercept Command Example
3
-
4
- A command that can be completely intercepted by hooks based on conditions.
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 InterceptResult(CommandResult):
13
- """
14
- Result of the intercept command execution.
15
- """
16
-
17
- def __init__(self, message: str, executed: bool, intercept_reason: Optional[str] = None,
18
- hook_data: Optional[Dict[str, Any]] = None):
19
- """
20
- Initialize intercept command result.
21
-
22
- Args:
23
- message: Result message
24
- executed: Whether the command was actually executed
25
- intercept_reason: Reason for interception (if any)
26
- hook_data: Data from hooks
27
- """
28
- self.message = message
29
- self.executed = executed
30
- self.intercept_reason = intercept_reason
31
- self.hook_data = hook_data or {}
32
-
33
- def to_dict(self) -> Dict[str, Any]:
34
- """
35
- Convert result to dictionary.
36
-
37
- Returns:
38
- Dict[str, Any]: Result as dictionary
39
- """
40
- return {
41
- "message": self.message,
42
- "executed": self.executed,
43
- "intercept_reason": self.intercept_reason,
44
- "hook_data": self.hook_data,
45
- "command_type": "intercept"
46
- }
47
-
48
- @classmethod
49
- def get_schema(cls) -> Dict[str, Any]:
50
- """
51
- Get JSON schema for the result.
52
-
53
- Returns:
54
- Dict[str, Any]: JSON schema
55
- """
56
- return {
57
- "type": "object",
58
- "properties": {
59
- "message": {"type": "string"},
60
- "executed": {"type": "boolean"},
61
- "intercept_reason": {"type": "string"},
62
- "hook_data": {"type": "object"},
63
- "command_type": {"type": "string"}
64
- }
65
- }
66
-
67
-
68
- class InterceptCommand(Command):
69
- """
70
- Intercept command for demonstrating hook interception.
71
- """
72
-
73
- name = "intercept"
74
- result_class = InterceptResult
75
-
76
- async def execute(self, action: Optional[str] = None,
77
- bypass_flag: Optional[int] = None, **kwargs) -> InterceptResult:
78
- """
79
- Execute intercept command.
80
-
81
- Args:
82
- action: Action to perform
83
- bypass_flag: Flag to determine if command should be bypassed (0 = bypass, 1 = execute)
84
- **kwargs: Additional parameters
85
-
86
- Returns:
87
- InterceptResult: Intercept command result
88
- """
89
- action = action or "default"
90
- bypass_flag = bypass_flag if bypass_flag is not None else 1
91
-
92
- # This should only execute if bypass_flag == 1
93
- # If bypass_flag == 0, hooks should intercept and return result
94
-
95
- return InterceptResult(
96
- message=f"Command executed with action: {action}",
97
- executed=True,
98
- intercept_reason=None,
99
- hook_data=kwargs
100
- )
101
-
102
- @classmethod
103
- def get_schema(cls) -> Dict[str, Any]:
104
- """
105
- Get JSON schema for command parameters.
106
-
107
- Returns:
108
- Dict[str, Any]: JSON schema
109
- """
110
- return {
111
- "type": "object",
112
- "properties": {
113
- "action": {
114
- "type": "string",
115
- "description": "Action to perform"
116
- },
117
- "bypass_flag": {
118
- "type": "integer",
119
- "enum": [0, 1],
120
- "description": "Flag to determine execution (0 = bypass, 1 = execute)"
121
- }
122
- }
123
- }
@@ -1,129 +0,0 @@
1
- """
2
- Test command for loadable commands testing.
3
-
4
- This command demonstrates the loadable commands functionality.
5
- """
6
-
7
- from typing import Any, Dict
8
-
9
- from mcp_proxy_adapter.commands.base import Command
10
- from mcp_proxy_adapter.commands.result import SuccessResult
11
-
12
-
13
- class TestCommandResult:
14
- """
15
- Result of test command execution.
16
- """
17
-
18
- def __init__(self, message: str, test_data: Dict[str, Any]):
19
- """
20
- Initialize test command result.
21
-
22
- Args:
23
- message: Result message
24
- test_data: Test data
25
- """
26
- self.message = message
27
- self.test_data = test_data
28
-
29
- def to_dict(self) -> Dict[str, Any]:
30
- """
31
- Convert result to dictionary.
32
-
33
- Returns:
34
- Dictionary representation of the result.
35
- """
36
- return {
37
- "success": True,
38
- "message": self.message,
39
- "test_data": self.test_data
40
- }
41
-
42
- @classmethod
43
- def get_schema(cls) -> Dict[str, Any]:
44
- """
45
- Get JSON schema for the result.
46
-
47
- Returns:
48
- JSON schema dictionary.
49
- """
50
- return {
51
- "type": "object",
52
- "properties": {
53
- "success": {
54
- "type": "boolean",
55
- "description": "Whether command was successful"
56
- },
57
- "message": {
58
- "type": "string",
59
- "description": "Result message"
60
- },
61
- "test_data": {
62
- "type": "object",
63
- "description": "Test data"
64
- }
65
- },
66
- "required": ["success", "message", "test_data"]
67
- }
68
-
69
-
70
- class TestCommand(Command):
71
- """
72
- Test command for loadable commands testing.
73
- """
74
-
75
- name = "test"
76
- result_class = TestCommandResult
77
-
78
- async def execute(self, **kwargs) -> TestCommandResult:
79
- """
80
- Execute test command.
81
-
82
- Args:
83
- **kwargs: Command parameters
84
-
85
- Returns:
86
- TestCommandResult with test information
87
- """
88
- # Get parameters
89
- test_param = kwargs.get("test_param", "default_value")
90
- echo_text = kwargs.get("echo_text", "Hello from loadable command!")
91
-
92
- # Create test data
93
- test_data = {
94
- "command_type": "loadable",
95
- "test_param": test_param,
96
- "echo_text": echo_text,
97
- "timestamp": "2025-08-12T09:45:00Z",
98
- "status": "working"
99
- }
100
-
101
- return TestCommandResult(
102
- message=f"Test command executed successfully with param: {test_param}",
103
- test_data=test_data
104
- )
105
-
106
- @classmethod
107
- def get_schema(cls) -> Dict[str, Any]:
108
- """
109
- Get JSON schema for command parameters.
110
-
111
- Returns:
112
- JSON schema dictionary.
113
- """
114
- return {
115
- "type": "object",
116
- "properties": {
117
- "test_param": {
118
- "type": "string",
119
- "description": "Test parameter",
120
- "default": "default_value"
121
- },
122
- "echo_text": {
123
- "type": "string",
124
- "description": "Text to echo",
125
- "default": "Hello from loadable command!"
126
- }
127
- },
128
- "additionalProperties": False
129
- }
@@ -1,103 +0,0 @@
1
- """
2
- Manually registered Echo Command
3
-
4
- This command must be manually registered in the server code.
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 ManualEchoResult(CommandResult):
13
- """
14
- Result of the manually registered echo command execution.
15
- """
16
-
17
- def __init__(self, message: str, manually_registered: bool = True):
18
- """
19
- Initialize manual echo command result.
20
-
21
- Args:
22
- message: Echoed message
23
- manually_registered: Flag indicating this was manually registered
24
- """
25
- self.message = message
26
- self.manually_registered = manually_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
- "manually_registered": self.manually_registered,
38
- "command_type": "manual_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
- "manually_registered": {"type": "boolean"},
54
- "command_type": {"type": "string"}
55
- }
56
- }
57
-
58
-
59
- class ManualEchoCommand(Command):
60
- """
61
- Manually registered echo command.
62
- """
63
-
64
- name = "manual_echo"
65
- result_class = ManualEchoResult
66
-
67
- async def execute(self, message: Optional[str] = None, **kwargs) -> ManualEchoResult:
68
- """
69
- Execute manually registered echo command.
70
-
71
- Args:
72
- message: Message to echo
73
- **kwargs: Additional parameters
74
-
75
- Returns:
76
- ManualEchoResult: Manual echo command result
77
- """
78
- if message is None:
79
- message = "Hello from manually registered command!"
80
-
81
- return ManualEchoResult(
82
- message=message,
83
- manually_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 manually registered command!"
101
- }
102
- }
103
- }