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