mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__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.

Potentially problematic release.


This version of mcp-proxy-adapter might be problematic. Click here for more details.

Files changed (269) hide show
  1. mcp_proxy_adapter/__init__.py +47 -0
  2. mcp_proxy_adapter/__main__.py +13 -0
  3. mcp_proxy_adapter/api/__init__.py +0 -0
  4. mcp_proxy_adapter/api/app.py +66 -0
  5. mcp_proxy_adapter/api/core/__init__.py +18 -0
  6. mcp_proxy_adapter/api/core/app_factory.py +400 -0
  7. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  8. mcp_proxy_adapter/api/core/registration_context.py +356 -0
  9. mcp_proxy_adapter/api/core/registration_manager.py +307 -0
  10. mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
  11. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  12. mcp_proxy_adapter/api/handlers.py +181 -0
  13. mcp_proxy_adapter/api/middleware/__init__.py +21 -0
  14. mcp_proxy_adapter/api/middleware/base.py +54 -0
  15. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
  16. mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
  17. mcp_proxy_adapter/api/middleware/factory.py +147 -0
  18. mcp_proxy_adapter/api/middleware/logging.py +31 -0
  19. mcp_proxy_adapter/api/middleware/performance.py +51 -0
  20. mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
  21. mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
  22. mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
  23. mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
  24. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  25. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  26. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  27. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  28. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  29. mcp_proxy_adapter/api/schemas.py +270 -0
  30. mcp_proxy_adapter/api/tool_integration.py +131 -0
  31. mcp_proxy_adapter/api/tools.py +163 -0
  32. mcp_proxy_adapter/cli/__init__.py +12 -0
  33. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  34. mcp_proxy_adapter/cli/commands/client.py +100 -0
  35. mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
  36. mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
  37. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  38. mcp_proxy_adapter/cli/commands/server.py +174 -0
  39. mcp_proxy_adapter/cli/commands/sets.py +132 -0
  40. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  41. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  42. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  43. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  44. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  45. mcp_proxy_adapter/cli/main.py +63 -0
  46. mcp_proxy_adapter/cli/parser.py +338 -0
  47. mcp_proxy_adapter/cli/validators.py +231 -0
  48. mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
  49. mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
  50. mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
  51. mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
  52. mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
  53. mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
  54. mcp_proxy_adapter/client/proxy.py +123 -0
  55. mcp_proxy_adapter/commands/__init__.py +66 -0
  56. mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
  57. mcp_proxy_adapter/commands/base.py +389 -0
  58. mcp_proxy_adapter/commands/builtin_commands.py +30 -0
  59. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  60. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  61. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  62. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  63. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  64. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  65. mcp_proxy_adapter/commands/catalog_manager.py +97 -0
  66. mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
  67. mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
  68. mcp_proxy_adapter/commands/command_registry.py +298 -0
  69. mcp_proxy_adapter/commands/config_command.py +102 -0
  70. mcp_proxy_adapter/commands/dependency_container.py +40 -0
  71. mcp_proxy_adapter/commands/dependency_manager.py +143 -0
  72. mcp_proxy_adapter/commands/echo_command.py +48 -0
  73. mcp_proxy_adapter/commands/health_command.py +142 -0
  74. mcp_proxy_adapter/commands/help_command.py +175 -0
  75. mcp_proxy_adapter/commands/hooks.py +172 -0
  76. mcp_proxy_adapter/commands/key_management_command.py +484 -0
  77. mcp_proxy_adapter/commands/load_command.py +123 -0
  78. mcp_proxy_adapter/commands/plugins_command.py +246 -0
  79. mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
  80. mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
  81. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  82. mcp_proxy_adapter/commands/registration_status_command.py +76 -0
  83. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  84. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  85. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  86. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  87. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  88. mcp_proxy_adapter/commands/reload_command.py +136 -0
  89. mcp_proxy_adapter/commands/result.py +157 -0
  90. mcp_proxy_adapter/commands/role_test_command.py +99 -0
  91. mcp_proxy_adapter/commands/roles_management_command.py +502 -0
  92. mcp_proxy_adapter/commands/security_command.py +472 -0
  93. mcp_proxy_adapter/commands/settings_command.py +113 -0
  94. mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
  95. mcp_proxy_adapter/commands/token_management_command.py +500 -0
  96. mcp_proxy_adapter/commands/transport_management_command.py +129 -0
  97. mcp_proxy_adapter/commands/unload_command.py +92 -0
  98. mcp_proxy_adapter/config.py +32 -0
  99. mcp_proxy_adapter/core/__init__.py +8 -0
  100. mcp_proxy_adapter/core/app_factory.py +560 -0
  101. mcp_proxy_adapter/core/app_runner.py +318 -0
  102. mcp_proxy_adapter/core/auth_validator.py +508 -0
  103. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  104. mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
  105. mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
  106. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  107. mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
  108. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
  109. mcp_proxy_adapter/core/certificate_utils.py +249 -0
  110. mcp_proxy_adapter/core/client.py +608 -0
  111. mcp_proxy_adapter/core/client_manager.py +271 -0
  112. mcp_proxy_adapter/core/client_security.py +411 -0
  113. mcp_proxy_adapter/core/config/__init__.py +18 -0
  114. mcp_proxy_adapter/core/config/config.py +237 -0
  115. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  116. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  117. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  118. mcp_proxy_adapter/core/config/simple_config.py +204 -0
  119. mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
  120. mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
  121. mcp_proxy_adapter/core/config_converter.py +252 -0
  122. mcp_proxy_adapter/core/config_validator.py +211 -0
  123. mcp_proxy_adapter/core/crl_utils.py +362 -0
  124. mcp_proxy_adapter/core/errors.py +276 -0
  125. mcp_proxy_adapter/core/job_manager.py +54 -0
  126. mcp_proxy_adapter/core/logging.py +250 -0
  127. mcp_proxy_adapter/core/mtls_asgi.py +140 -0
  128. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  129. mcp_proxy_adapter/core/mtls_proxy.py +229 -0
  130. mcp_proxy_adapter/core/mtls_server.py +154 -0
  131. mcp_proxy_adapter/core/protocol_manager.py +232 -0
  132. mcp_proxy_adapter/core/proxy/__init__.py +19 -0
  133. mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
  134. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
  135. mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
  136. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  137. mcp_proxy_adapter/core/proxy_client.py +184 -0
  138. mcp_proxy_adapter/core/proxy_registration.py +80 -0
  139. mcp_proxy_adapter/core/role_utils.py +103 -0
  140. mcp_proxy_adapter/core/security_adapter.py +343 -0
  141. mcp_proxy_adapter/core/security_factory.py +96 -0
  142. mcp_proxy_adapter/core/security_integration.py +342 -0
  143. mcp_proxy_adapter/core/server_adapter.py +251 -0
  144. mcp_proxy_adapter/core/server_engine.py +217 -0
  145. mcp_proxy_adapter/core/settings.py +260 -0
  146. mcp_proxy_adapter/core/signal_handler.py +107 -0
  147. mcp_proxy_adapter/core/ssl_utils.py +161 -0
  148. mcp_proxy_adapter/core/transport_manager.py +153 -0
  149. mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
  150. mcp_proxy_adapter/core/utils.py +101 -0
  151. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  152. mcp_proxy_adapter/core/validation/config_validator.py +219 -0
  153. mcp_proxy_adapter/core/validation/file_validator.py +131 -0
  154. mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
  155. mcp_proxy_adapter/core/validation/security_validator.py +140 -0
  156. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  157. mcp_proxy_adapter/custom_openapi.py +58 -0
  158. mcp_proxy_adapter/examples/__init__.py +16 -0
  159. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  160. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  161. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  162. mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
  163. mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
  164. mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
  165. mcp_proxy_adapter/examples/check_config.py +413 -0
  166. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  167. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  168. mcp_proxy_adapter/examples/config_builder.py +234 -0
  169. mcp_proxy_adapter/examples/config_cli.py +282 -0
  170. mcp_proxy_adapter/examples/create_test_configs.py +174 -0
  171. mcp_proxy_adapter/examples/debug_request_state.py +130 -0
  172. mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
  173. mcp_proxy_adapter/examples/demo_client.py +287 -0
  174. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  175. mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
  176. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
  177. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
  178. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
  179. mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
  180. mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
  181. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
  182. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
  183. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
  184. mcp_proxy_adapter/examples/full_application/main.py +311 -0
  185. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
  186. mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
  187. mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
  188. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
  189. mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
  190. mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
  191. mcp_proxy_adapter/examples/generate_config.py +502 -0
  192. mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
  193. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  194. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  195. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  196. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  197. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  198. mcp_proxy_adapter/examples/required_certificates.py +208 -0
  199. mcp_proxy_adapter/examples/run_example.py +77 -0
  200. mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
  201. mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
  202. mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
  203. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  204. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  205. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  206. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  207. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  208. mcp_proxy_adapter/examples/security_test_client.py +72 -0
  209. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  210. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  211. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  212. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  213. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  214. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  215. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  216. mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
  217. mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
  218. mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
  219. mcp_proxy_adapter/examples/test_config.py +205 -0
  220. mcp_proxy_adapter/examples/test_config_builder.py +110 -0
  221. mcp_proxy_adapter/examples/test_examples.py +308 -0
  222. mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
  223. mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
  224. mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
  225. mcp_proxy_adapter/examples/universal_client.py +674 -0
  226. mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
  227. mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
  228. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
  229. mcp_proxy_adapter/integrations/__init__.py +25 -0
  230. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  231. mcp_proxy_adapter/main.py +311 -0
  232. mcp_proxy_adapter/openapi.py +375 -0
  233. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  234. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  235. mcp_proxy_adapter/schemas/roles.json +37 -0
  236. mcp_proxy_adapter/schemas/roles_schema.json +162 -0
  237. mcp_proxy_adapter/version.py +5 -0
  238. mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
  239. mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
  240. {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
  241. mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
  242. mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
  243. adapters/__init__.py +0 -16
  244. analyzers/__init__.py +0 -14
  245. analyzers/docstring_analyzer.py +0 -199
  246. analyzers/type_analyzer.py +0 -151
  247. cli/__init__.py +0 -12
  248. cli/__main__.py +0 -79
  249. cli/command_runner.py +0 -233
  250. dispatchers/__init__.py +0 -14
  251. dispatchers/base_dispatcher.py +0 -85
  252. dispatchers/json_rpc_dispatcher.py +0 -198
  253. generators/__init__.py +0 -14
  254. generators/endpoint_generator.py +0 -172
  255. generators/openapi_generator.py +0 -254
  256. generators/rest_api_generator.py +0 -207
  257. mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
  258. mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
  259. mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
  260. mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
  261. openapi_schema/__init__.py +0 -38
  262. openapi_schema/command_registry.py +0 -312
  263. openapi_schema/rest_schema.py +0 -510
  264. openapi_schema/rpc_generator.py +0 -307
  265. openapi_schema/rpc_schema.py +0 -416
  266. validators/__init__.py +0 -14
  267. validators/base_validator.py +0 -23
  268. validators/docstring_validator.py +0 -75
  269. validators/metadata_validator.py +0 -76
@@ -0,0 +1,52 @@
1
+ """
2
+ Dynamic Calculator Command
3
+ This module demonstrates a dynamically loaded command implementation for the full application example.
4
+ Author: Vasiliy Zdanovskiy
5
+ email: vasilyvz@gmail.com
6
+ """
7
+
8
+ from mcp_proxy_adapter.commands.base import BaseCommand
9
+ from mcp_proxy_adapter.commands.result import CommandResult
10
+
11
+
12
+ class CalculatorResult(CommandResult):
13
+ """Result class for calculator command."""
14
+
15
+ def __init__(self, operation: str, result: float, expression: str):
16
+ self.operation = operation
17
+ self.result = result
18
+ self.expression = expression
19
+
20
+
21
+
22
+
23
+ class DynamicCalculatorCommand(BaseCommand):
24
+ """Dynamic calculator command implementation."""
25
+
26
+
27
+
28
+
29
+ async def execute(self, params: Dict[str, Any]) -> CalculatorResult:
30
+ """Execute the calculator command."""
31
+ operation = params.get("operation")
32
+ a = params.get("a")
33
+ b = params.get("b")
34
+ if operation == "add":
35
+ result = a + b
36
+ expression = f"{a} + {b}"
37
+ elif operation == "subtract":
38
+ result = a - b
39
+ expression = f"{a} - {b}"
40
+ elif operation == "multiply":
41
+ result = a * b
42
+ expression = f"{a} * {b}"
43
+ elif operation == "divide":
44
+ if b == 0:
45
+ raise ValueError("Division by zero is not allowed")
46
+ result = a / b
47
+ expression = f"{a} / {b}"
48
+ else:
49
+ raise ValueError(f"Unknown operation: {operation}")
50
+ return CalculatorResult(
51
+ operation=operation, result=result, expression=expression
52
+ )
@@ -0,0 +1,32 @@
1
+ """
2
+ Echo command implementation.
3
+ """
4
+ from mcp_proxy_adapter.commands.base import BaseCommand
5
+ from mcp_proxy_adapter.core.errors import MicroserviceError
6
+
7
+
8
+ class EchoCommand(BaseCommand):
9
+ """Echo command that returns the input message."""
10
+
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.name = "echo"
14
+ self.description = "Echo command that returns the input message"
15
+ self.version = "1.0.0"
16
+
17
+
18
+ async def execute(self, params: dict) -> dict:
19
+ """Execute echo command."""
20
+ try:
21
+ message = params.get("message", "")
22
+ return {
23
+ "echo": message,
24
+ "timestamp": self._get_timestamp()
25
+ }
26
+ except Exception as e:
27
+ raise MicroserviceError(f"Echo command failed: {str(e)}")
28
+
29
+ def _get_timestamp(self):
30
+ """Get current timestamp."""
31
+ import time
32
+ return time.time()
@@ -0,0 +1,54 @@
1
+ """
2
+ Help command implementation.
3
+ """
4
+ from mcp_proxy_adapter.commands.base import BaseCommand
5
+ from mcp_proxy_adapter.core.errors import MicroserviceError
6
+
7
+
8
+ class HelpCommand(BaseCommand):
9
+ """Help command that provides usage information."""
10
+
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.name = "help"
14
+ self.description = "Get help information"
15
+ self.version = "1.0.0"
16
+
17
+
18
+ async def execute(self, params: dict) -> dict:
19
+ """Execute help command."""
20
+ try:
21
+ command = params.get("command")
22
+
23
+ if command:
24
+ # Get help for specific command
25
+ help_info = self._get_command_help(command)
26
+ return {
27
+ "command": command,
28
+ "help": help_info,
29
+ "timestamp": self._get_timestamp()
30
+ }
31
+ else:
32
+ # Get general help
33
+ return {
34
+ "help": "MCP Proxy Adapter - Available commands: echo, list, health, help",
35
+ "usage": "Use 'help' with a command name to get specific help",
36
+ "timestamp": self._get_timestamp()
37
+ }
38
+ except Exception as e:
39
+ raise MicroserviceError(f"Help command failed: {str(e)}")
40
+
41
+ def _get_command_help(self, command: str) -> str:
42
+ """Get help for specific command."""
43
+ help_map = {
44
+ "echo": "Echo command - returns the input message. Usage: {'message': 'your message'}",
45
+ "list": "List command - returns available commands. Usage: {}",
46
+ "health": "Health command - returns server health status. Usage: {}",
47
+ "help": "Help command - provides usage information. Usage: {'command': 'command_name'} (optional)"
48
+ }
49
+ return help_map.get(command, f"No help available for command '{command}'")
50
+
51
+ def _get_timestamp(self):
52
+ """Get current timestamp."""
53
+ import time
54
+ return time.time()
@@ -0,0 +1,57 @@
1
+ """
2
+ List command implementation.
3
+ """
4
+ from mcp_proxy_adapter.commands.base import BaseCommand
5
+ from mcp_proxy_adapter.core.errors import MicroserviceError
6
+
7
+
8
+ class ListCommand(BaseCommand):
9
+ """List command that returns available commands."""
10
+
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.name = "list"
14
+ self.description = "List available commands"
15
+ self.version = "1.0.0"
16
+
17
+
18
+ async def execute(self, params: dict) -> dict:
19
+ """Execute list command."""
20
+ try:
21
+ # This is a simplified list - in a real implementation,
22
+ # this would query the command registry
23
+ commands = [
24
+ {
25
+ "name": "echo",
26
+ "description": "Echo command that returns the input message",
27
+ "version": "1.0.0"
28
+ },
29
+ {
30
+ "name": "list",
31
+ "description": "List available commands",
32
+ "version": "1.0.0"
33
+ },
34
+ {
35
+ "name": "health",
36
+ "description": "Health check command",
37
+ "version": "1.0.0"
38
+ },
39
+ {
40
+ "name": "help",
41
+ "description": "Help command",
42
+ "version": "1.0.0"
43
+ }
44
+ ]
45
+
46
+ return {
47
+ "commands": commands,
48
+ "count": len(commands),
49
+ "timestamp": self._get_timestamp()
50
+ }
51
+ except Exception as e:
52
+ raise MicroserviceError(f"List command failed: {str(e)}")
53
+
54
+ def _get_timestamp(self):
55
+ """Get current timestamp."""
56
+ import time
57
+ return time.time()
@@ -0,0 +1,5 @@
1
+ """Full Application Hooks.
2
+
3
+ Application and command hooks for the full application example.
4
+ """
5
+
@@ -0,0 +1,29 @@
1
+ """
2
+ Application Hooks
3
+ This module demonstrates application-level hooks in the full application example.
4
+ Author: Vasiliy Zdanovskiy
5
+ email: vasilyvz@gmail.com
6
+ """
7
+
8
+ import logging
9
+ from datetime import datetime
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class ApplicationHooks:
15
+ """Application-level hooks."""
16
+
17
+ @staticmethod
18
+
19
+ @staticmethod
20
+
21
+ @staticmethod
22
+
23
+ @staticmethod
24
+
25
+ @staticmethod
26
+
27
+ @staticmethod
28
+
29
+ @staticmethod
@@ -0,0 +1,27 @@
1
+ """
2
+ Built-in Command Hooks
3
+ This module demonstrates hooks for built-in commands in the full application example.
4
+ Author: Vasiliy Zdanovskiy
5
+ email: vasilyvz@gmail.com
6
+ """
7
+
8
+ import logging
9
+ from datetime import datetime
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class BuiltinCommandHooks:
15
+ """Hooks for built-in commands."""
16
+
17
+ @staticmethod
18
+
19
+ @staticmethod
20
+
21
+ @staticmethod
22
+
23
+ @staticmethod
24
+
25
+ @staticmethod
26
+
27
+ @staticmethod
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Full Application Example
4
+ This is a complete application that demonstrates all features of MCP Proxy Adapter framework:
5
+ - Built-in commands
6
+ - Custom commands
7
+ - Dynamically loaded commands
8
+ - Built-in command hooks
9
+ - Application hooks
10
+ Author: Vasiliy Zdanovskiy
11
+ email: vasilyvz@gmail.com
12
+ """
13
+ import argparse
14
+ import asyncio
15
+ import json
16
+ from pathlib import Path
17
+
18
+ from mcp_proxy_adapter.api.app import create_app
19
+ from mcp_proxy_adapter.core.server_engine import ServerEngineFactory
20
+ from mcp_proxy_adapter.core.server_adapter import ServerConfigAdapter
21
+ from mcp_proxy_adapter.client.proxy import ProxyClient
22
+ from mcp_proxy_adapter.commands.command_registry import registry
23
+
24
+
25
+ def register_all_commands():
26
+ """Register all available commands (built-in, load, queue)."""
27
+ from mcp_proxy_adapter.commands.load_command import LoadCommand
28
+
29
+ # Register load command
30
+ registry._commands["load"] = LoadCommand
31
+ registry._command_types["load"] = "builtin"
32
+
33
+ # Register queue commands (will fail gracefully if queuemgr not available)
34
+ try:
35
+ from mcp_proxy_adapter.commands.queue_commands import (
36
+ QueueAddJobCommand,
37
+ QueueStartJobCommand,
38
+ QueueStopJobCommand,
39
+ QueueDeleteJobCommand,
40
+ QueueGetJobStatusCommand,
41
+ QueueListJobsCommand,
42
+ QueueHealthCommand,
43
+ )
44
+
45
+ registry._commands["queue_add_job"] = QueueAddJobCommand
46
+ registry._command_types["queue_add_job"] = "builtin"
47
+ registry._commands["queue_start_job"] = QueueStartJobCommand
48
+ registry._command_types["queue_start_job"] = "builtin"
49
+ registry._commands["queue_stop_job"] = QueueStopJobCommand
50
+ registry._command_types["queue_stop_job"] = "builtin"
51
+ registry._commands["queue_delete_job"] = QueueDeleteJobCommand
52
+ registry._command_types["queue_delete_job"] = "builtin"
53
+ registry._commands["queue_get_job_status"] = QueueGetJobStatusCommand
54
+ registry._command_types["queue_get_job_status"] = "builtin"
55
+ registry._commands["queue_list_jobs"] = QueueListJobsCommand
56
+ registry._command_types["queue_list_jobs"] = "builtin"
57
+ registry._commands["queue_health"] = QueueHealthCommand
58
+ registry._command_types["queue_health"] = "builtin"
59
+ print("✅ Queue commands registered")
60
+ except Exception as e:
61
+ print(f"⚠️ Queue commands not available: {e}")
62
+
63
+
64
+ def main():
65
+ """Minimal runnable entrypoint for full application example."""
66
+ parser = argparse.ArgumentParser(description="MCP Proxy Adapter Full Application")
67
+ parser.add_argument("--config", required=True, help="Path to configuration file")
68
+ parser.add_argument("--port", type=int, help="Port to run server on (override)")
69
+ parser.add_argument("--host", default="0.0.0.0", help="Host to bind to")
70
+ args = parser.parse_args()
71
+
72
+ cfg_path = Path(args.config)
73
+ if not cfg_path.exists():
74
+ print(f"❌ Configuration file not found: {cfg_path}")
75
+ raise SystemExit(1)
76
+
77
+ try:
78
+ with cfg_path.open("r", encoding="utf-8") as f:
79
+ app_config = json.load(f)
80
+ except Exception as exc: # noqa: BLE001
81
+ print(f"❌ Failed to load configuration: {exc}")
82
+ raise SystemExit(1)
83
+
84
+ if args.port:
85
+ app_config.setdefault("server", {}).update({"port": args.port})
86
+ print(f"🔧 Overriding port to {args.port}")
87
+ if args.host:
88
+ app_config.setdefault("server", {}).update({"host": args.host})
89
+ print(f"🔧 Overriding host to {args.host}")
90
+
91
+ # Strict protocol checks: forbid any form of mTLS over HTTP
92
+ # Work directly with server section (SimpleConfig format)
93
+ server_cfg = app_config.get("server", {})
94
+ proto = str(server_cfg.get("protocol", "http")).lower()
95
+
96
+ # Get certificates from server section (SimpleConfig format)
97
+ cert_file = server_cfg.get("cert_file")
98
+ key_file = server_cfg.get("key_file")
99
+ ca_cert_file = server_cfg.get("ca_cert_file")
100
+
101
+ transport = app_config.get("transport", {}) or {}
102
+ require_client_cert = bool(transport.get("verify_client") or (proto == "mtls"))
103
+
104
+ if proto == "http":
105
+ if require_client_cert:
106
+ raise SystemExit(
107
+ "CRITICAL CONFIG ERROR: mTLS (client certificate verification) cannot be used with HTTP. "
108
+ "Switch protocol to 'mtls' (or 'https' without client verification), and configure SSL certificates."
109
+ )
110
+
111
+ if proto == "mtls":
112
+ if not (cert_file and key_file):
113
+ raise SystemExit(
114
+ "CRITICAL CONFIG ERROR: Protocol 'mtls' requires server.cert_file and server.key_file."
115
+ )
116
+ if not require_client_cert:
117
+ raise SystemExit(
118
+ "CRITICAL CONFIG ERROR: Protocol 'mtls' requires client certificate verification. "
119
+ "Set transport.verify_client=true."
120
+ )
121
+ if not ca_cert_file:
122
+ raise SystemExit(
123
+ "CRITICAL CONFIG ERROR: 'mtls' requires server.ca_cert_file."
124
+ )
125
+
126
+ app = create_app(
127
+ title="Full Application Example",
128
+ description="Complete MCP Proxy Adapter with all features",
129
+ version="1.0.0",
130
+ app_config=app_config,
131
+ config_path=str(cfg_path),
132
+ )
133
+
134
+ port = int(app_config.get("server", {}).get("port", 8080))
135
+ host = app_config.get("server", {}).get("host", args.host)
136
+
137
+ print("🚀 Starting Full Application Example")
138
+ print(f"📋 Configuration: {cfg_path}")
139
+ print("============================================================")
140
+
141
+ # Register all commands
142
+ register_all_commands()
143
+ print(
144
+ f"📋 Registered commands: {', '.join(sorted(registry.get_all_commands().keys()))}"
145
+ )
146
+
147
+ # Prepare server configuration for ServerEngine
148
+ server_config = {
149
+ "host": host,
150
+ "port": port,
151
+ "log_level": "info",
152
+ "reload": False,
153
+ }
154
+
155
+ # Add SSL configuration from server section (SimpleConfig format)
156
+ cert = server_cfg.get("cert_file")
157
+ key = server_cfg.get("key_file")
158
+ ca = server_cfg.get("ca_cert_file")
159
+ verify_client = (server_cfg.get("protocol") == "mtls") or transport.get(
160
+ "verify_client", False
161
+ )
162
+
163
+ if cert and key:
164
+ server_config["certfile"] = cert
165
+ server_config["keyfile"] = key
166
+ if ca:
167
+ server_config["ca_certs"] = ca
168
+ if verify_client:
169
+ server_config["verify_mode"] = 2 # ssl.CERT_REQUIRED
170
+ # Check hostname setting from server section
171
+ if server_cfg.get("check_hostname") is not None:
172
+ server_config["check_hostname"] = server_cfg["check_hostname"]
173
+
174
+ # Optional proxy registration - support both old (proxy_registration) and new (registration) formats
175
+ pr = {}
176
+ if isinstance(app_config, dict):
177
+ # Try new SimpleConfig format first (registration section)
178
+ registration = app_config.get("registration", {})
179
+ if registration and registration.get("enabled"):
180
+ pr = {
181
+ "enabled": True,
182
+ "proxy_url": f"{registration.get('protocol', 'http')}://{registration.get('host', 'localhost')}:{registration.get('port', 3005)}",
183
+ "server_id": registration.get("server_id")
184
+ or registration.get("server_name"),
185
+ "server_name": registration.get("server_name")
186
+ or registration.get("server_id"),
187
+ "auto_register_on_startup": registration.get("auto_on_startup", True),
188
+ "auto_unregister_on_shutdown": registration.get(
189
+ "auto_on_shutdown", True
190
+ ),
191
+ "heartbeat": {
192
+ "enabled": True,
193
+ "interval": (
194
+ registration.get("heartbeat", {}).get("interval", 30)
195
+ if isinstance(registration.get("heartbeat"), dict)
196
+ else 30
197
+ ),
198
+ },
199
+ }
200
+ # Fallback to old format (proxy_registration section)
201
+ elif app_config.get("proxy_registration"):
202
+ pr = app_config.get("proxy_registration", {})
203
+ # Also check proxy_client (SimpleConfig old format)
204
+ elif app_config.get("proxy_client", {}).get("enabled"):
205
+ pc = app_config.get("proxy_client", {})
206
+ pr = {
207
+ "enabled": True,
208
+ "proxy_url": f"{pc.get('protocol', 'http')}://{pc.get('host', 'localhost')}:{pc.get('port', 3005)}",
209
+ "server_id": pc.get("server_id") or pc.get("server_name"),
210
+ "server_name": pc.get("server_name") or pc.get("server_id"),
211
+ "auto_register_on_startup": (
212
+ pc.get("registration", {}).get("auto_on_startup", True)
213
+ if isinstance(pc.get("registration"), dict)
214
+ else True
215
+ ),
216
+ "auto_unregister_on_shutdown": (
217
+ pc.get("registration", {}).get("auto_on_shutdown", True)
218
+ if isinstance(pc.get("registration"), dict)
219
+ else True
220
+ ),
221
+ "heartbeat": pc.get("heartbeat", {}),
222
+ }
223
+
224
+ name = pr.get("server_id") or pr.get("server_name") or "mcp-adapter"
225
+ scheme = (
226
+ "https"
227
+ if str(app_config.get("server", {}).get("protocol", "http"))
228
+ in ("https", "mtls")
229
+ else "http"
230
+ )
231
+ advertised_host = (
232
+ app_config.get("server", {}).get("advertised_host") or "mcp-adapter"
233
+ )
234
+ advertised_url = f"{scheme}://{advertised_host}:{port}"
235
+
236
+ async def _run():
237
+ """Run server with proxy registration and heartbeat."""
238
+ heartbeat_task = None
239
+ try:
240
+ if pr.get("enabled") and pr.get("proxy_url"):
241
+ pc = ProxyClient(pr["proxy_url"])
242
+ try:
243
+ await pc.register(
244
+ name=name,
245
+ url=advertised_url,
246
+ capabilities=["jsonrpc"],
247
+ metadata={},
248
+ )
249
+ print(f"✅ Registered on proxy as {name} -> {advertised_url}")
250
+ except Exception as exc: # noqa: BLE001
251
+ print(f"⚠️ Proxy registration failed: {exc}")
252
+
253
+ async def _hb():
254
+ interval = int((pr.get("heartbeat") or {}).get("interval", 15))
255
+ while True:
256
+ try:
257
+ await pc.heartbeat(name=name, url=advertised_url)
258
+ except Exception:
259
+ pass
260
+ await asyncio.sleep(max(2, interval))
261
+
262
+ heartbeat_task = asyncio.create_task(_hb())
263
+
264
+ # Use ServerEngine with hypercorn (via ServerEngineFactory)
265
+ engine = ServerEngineFactory.get_engine("hypercorn")
266
+ if not engine:
267
+ raise RuntimeError("Hypercorn engine not available")
268
+
269
+ # Run server using hypercorn engine
270
+ # Use create_task instead of run_server to avoid nested event loop
271
+ from hypercorn.asyncio import serve
272
+ from hypercorn.config import Config as HypercornConfig
273
+
274
+ hypercorn_config = HypercornConfig()
275
+ hypercorn_config.bind = [f"{host}:{port}"]
276
+ hypercorn_config.loglevel = "info"
277
+
278
+ # Add SSL configuration from server section (SimpleConfig format)
279
+ server_cfg = app_config.get("server", {})
280
+ cert = server_cfg.get("cert_file")
281
+ key = server_cfg.get("key_file")
282
+ ca = server_cfg.get("ca_cert_file")
283
+ verify_client = (server_cfg.get("protocol") == "mtls") or app_config.get(
284
+ "transport", {}
285
+ ).get("verify_client", False)
286
+
287
+ if cert and key:
288
+ hypercorn_config.certfile = cert
289
+ hypercorn_config.keyfile = key
290
+ if ca:
291
+ hypercorn_config.ca_certs = ca
292
+ if verify_client:
293
+ hypercorn_config.verify_mode = 2 # ssl.CERT_REQUIRED
294
+
295
+ await serve(app, hypercorn_config)
296
+ finally:
297
+ if heartbeat_task:
298
+ heartbeat_task.cancel()
299
+ if pr.get("enabled") and pr.get("proxy_url"):
300
+ try:
301
+ pc = ProxyClient(pr["proxy_url"])
302
+ await pc.unregister(name)
303
+ print(f"🛑 Unregistered from proxy: {name}")
304
+ except Exception:
305
+ pass
306
+
307
+ asyncio.run(_run())
308
+
309
+
310
+ if __name__ == "__main__":
311
+ main()