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,105 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ CLI command: config generate (Simple configuration generator)
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import sys
12
+ from argparse import Namespace
13
+
14
+ from mcp_proxy_adapter.core.config.simple_config_generator import SimpleConfigGenerator
15
+
16
+
17
+ def config_generate_command(args: Namespace) -> int:
18
+ generator = SimpleConfigGenerator()
19
+ out = generator.generate(
20
+ protocol=args.protocol,
21
+ with_proxy=args.with_proxy,
22
+ out_path=args.out,
23
+ # Server parameters
24
+ server_host=getattr(args, "server_host", None),
25
+ server_port=getattr(args, "server_port", None),
26
+ server_cert_file=getattr(args, "server_cert_file", None),
27
+ server_key_file=getattr(args, "server_key_file", None),
28
+ server_ca_cert_file=getattr(args, "server_ca_cert_file", None),
29
+ server_crl_file=getattr(args, "server_crl_file", None),
30
+ # Client parameters
31
+ client_enabled=getattr(args, "client_enabled", False),
32
+ client_protocol=getattr(args, "client_protocol", None),
33
+ client_cert_file=getattr(args, "client_cert_file", None),
34
+ client_key_file=getattr(args, "client_key_file", None),
35
+ client_ca_cert_file=getattr(args, "client_ca_cert_file", None),
36
+ client_crl_file=getattr(args, "client_crl_file", None),
37
+ # Registration parameters
38
+ registration_host=getattr(args, "registration_host", None),
39
+ registration_port=getattr(args, "registration_port", None),
40
+ registration_protocol=getattr(args, "registration_protocol", None),
41
+ registration_cert_file=getattr(args, "registration_cert_file", None),
42
+ registration_key_file=getattr(args, "registration_key_file", None),
43
+ registration_ca_cert_file=getattr(args, "registration_ca_cert_file", None),
44
+ registration_crl_file=getattr(args, "registration_crl_file", None),
45
+ )
46
+ print(f"✅ Configuration generated: {out}")
47
+ return 0
48
+
49
+
50
+ def main() -> int:
51
+ """Main entry point for adapter-cfg-gen CLI command."""
52
+ parser = argparse.ArgumentParser(
53
+ prog="adapter-cfg-gen",
54
+ description="Generate simple configuration file for MCP Proxy Adapter"
55
+ )
56
+ parser.add_argument(
57
+ '--protocol',
58
+ required=True,
59
+ choices=['http', 'https', 'mtls'],
60
+ help='Server/proxy protocol'
61
+ )
62
+ parser.add_argument(
63
+ '--with-proxy',
64
+ action='store_true',
65
+ help='Enable proxy registration (deprecated, use --registration-* parameters)'
66
+ )
67
+ parser.add_argument(
68
+ '--out',
69
+ default='config.json',
70
+ help='Output config path (default: config.json)'
71
+ )
72
+
73
+ # Server parameters
74
+ parser.add_argument('--server-host', help='Server host (default: 0.0.0.0)')
75
+ parser.add_argument('--server-port', type=int, help='Server port (default: 8080)')
76
+ parser.add_argument('--server-cert-file', help='Server certificate file path')
77
+ parser.add_argument('--server-key-file', help='Server key file path')
78
+ parser.add_argument('--server-ca-cert-file', help='Server CA certificate file path')
79
+ parser.add_argument('--server-crl-file', help='Server CRL file path')
80
+
81
+ # Client parameters
82
+ parser.add_argument('--client-enabled', action='store_true', help='Enable client configuration')
83
+ parser.add_argument('--client-protocol', choices=['http', 'https', 'mtls'], help='Client protocol')
84
+ parser.add_argument('--client-cert-file', help='Client certificate file path')
85
+ parser.add_argument('--client-key-file', help='Client key file path')
86
+ parser.add_argument('--client-ca-cert-file', help='Client CA certificate file path')
87
+ parser.add_argument('--client-crl-file', help='Client CRL file path')
88
+
89
+ # Registration parameters
90
+ parser.add_argument('--registration-host', help='Registration proxy host (default: localhost)')
91
+ parser.add_argument('--registration-port', type=int, help='Registration proxy port (default: 3005)')
92
+ parser.add_argument('--registration-protocol', choices=['http', 'https', 'mtls'], help='Registration protocol')
93
+ parser.add_argument('--registration-cert-file', help='Registration certificate file path')
94
+ parser.add_argument('--registration-key-file', help='Registration key file path')
95
+ parser.add_argument('--registration-ca-cert-file', help='Registration CA certificate file path')
96
+ parser.add_argument('--registration-crl-file', help='Registration CRL file path')
97
+
98
+ args = parser.parse_args()
99
+ return config_generate_command(args)
100
+
101
+
102
+ if __name__ == "__main__":
103
+ sys.exit(main())
104
+
105
+
@@ -0,0 +1,94 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ CLI command: config validate (Configuration validation)
6
+ Supports both SimpleConfig and full configuration formats.
7
+ Uses the same ConfigValidator as server startup.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import json
14
+ import sys
15
+ from argparse import Namespace
16
+ from pathlib import Path
17
+
18
+ from mcp_proxy_adapter.core.validation.config_validator import ConfigValidator
19
+
20
+
21
+ def config_validate_command(args: Namespace) -> int:
22
+ """
23
+ Validate configuration file using ConfigValidator.
24
+
25
+ This uses the same validator as server startup to ensure consistency.
26
+ """
27
+ config_file = Path(args.file)
28
+
29
+ if not config_file.exists():
30
+ print(f"❌ Configuration file not found: {config_file}")
31
+ return 1
32
+
33
+ try:
34
+ # Load configuration
35
+ with open(config_file, 'r', encoding='utf-8') as f:
36
+ config_data = json.load(f)
37
+ except json.JSONDecodeError as e:
38
+ print(f"❌ Invalid JSON in configuration file: {e}")
39
+ return 1
40
+ except Exception as e:
41
+ print(f"❌ Failed to load config: {e}")
42
+ return 1
43
+
44
+ # Use the same ConfigValidator as server startup
45
+ validator = ConfigValidator(config_path=str(config_file))
46
+ validator.config_data = config_data
47
+ validation_results = validator.validate_config()
48
+
49
+ # Separate errors and warnings
50
+ errors = [r for r in validation_results if r.level == "error"]
51
+ warnings = [r for r in validation_results if r.level == "warning"]
52
+
53
+ if errors:
54
+ print("❌ Validation failed:")
55
+ for err in errors:
56
+ section_info = f" ({err.section}" + (f".{err.key}" if err.key else "") + ")" if err.section else ""
57
+ print(f" - {err.message}{section_info}")
58
+ if warnings:
59
+ print("\n⚠️ Warnings:")
60
+ for warn in warnings:
61
+ section_info = f" ({warn.section}" + (f".{warn.key}" if warn.key else "") + ")" if warn.section else ""
62
+ print(f" - {warn.message}{section_info}")
63
+ return 1
64
+
65
+ if warnings:
66
+ print("✅ Validation passed with warnings:")
67
+ for warn in warnings:
68
+ section_info = f" ({warn.section}" + (f".{warn.key}" if warn.key else "") + ")" if warn.section else ""
69
+ print(f" ⚠️ {warn.message}{section_info}")
70
+ return 0
71
+
72
+ print("✅ Validation OK")
73
+ return 0
74
+
75
+
76
+ def main() -> int:
77
+ """Main entry point for adapter-cfg-val CLI command."""
78
+ parser = argparse.ArgumentParser(
79
+ prog="adapter-cfg-val",
80
+ description="Validate configuration file for MCP Proxy Adapter"
81
+ )
82
+ parser.add_argument(
83
+ '--file',
84
+ required=True,
85
+ help='Path to configuration file'
86
+ )
87
+
88
+ args = parser.parse_args()
89
+ return config_validate_command(args)
90
+
91
+
92
+ if __name__ == "__main__":
93
+ sys.exit(main())
94
+
@@ -0,0 +1,259 @@
1
+ """
2
+ Generate Command
3
+
4
+ This module implements the generate command for creating configuration files.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ import json
11
+ from pathlib import Path
12
+ from typing import Dict, Any, Optional
13
+
14
+ # Import the existing config generator
15
+ try:
16
+ from mcp_proxy_adapter.examples.config_builder import generate_complete_config
17
+ from mcp_proxy_adapter.core.config_validator import ConfigValidator
18
+ VALIDATION_AVAILABLE = True
19
+ except ImportError:
20
+ VALIDATION_AVAILABLE = False
21
+ print("Warning: Configuration validation not available. Install the package to enable validation.")
22
+
23
+
24
+ class GenerateCommand:
25
+ """Command for generating configuration files."""
26
+
27
+ def __init__(self):
28
+ """Initialize the generate command."""
29
+ pass
30
+
31
+ def execute(self, args: Dict[str, Any]) -> int:
32
+ """
33
+ Execute the generate command.
34
+
35
+ Args:
36
+ args: Parsed command arguments
37
+
38
+ Returns:
39
+ Exit code (0 for success, 1 for error)
40
+ """
41
+ try:
42
+ # Handle special cases
43
+ if args.get('all'):
44
+ return self._generate_all_configs(args)
45
+
46
+ # Generate single configuration
47
+ return self._generate_single_config(args)
48
+
49
+ except Exception as e:
50
+ print(f"❌ Error generating configuration: {e}")
51
+ return 1
52
+
53
+ def _generate_single_config(self, args: Dict[str, Any]) -> int:
54
+ """Generate a single configuration file."""
55
+ # Create configuration
56
+ config = self._create_config_from_args(args)
57
+
58
+ # Save configuration
59
+ if args.get('stdout'):
60
+ # Output to stdout
61
+ print(json.dumps(config, indent=2, ensure_ascii=False))
62
+ else:
63
+ # Save to file
64
+ config_file = self._save_config(config, args)
65
+ print(f"✅ Configuration saved to: {config_file}")
66
+
67
+ return 0
68
+
69
+ def _generate_all_configs(self, args: Dict[str, Any]) -> int:
70
+ """Generate all standard configurations."""
71
+ print("🔧 Generating MCP Proxy Adapter configurations...")
72
+ print("=" * 60)
73
+
74
+ # Define all standard configurations
75
+ configs = [
76
+ # HTTP configurations
77
+ ("http", False, False, 20000),
78
+ ("http", True, True, 20001), # token + roles
79
+ ("http", True, False, 20002), # token only
80
+
81
+ # HTTPS configurations
82
+ ("https", False, False, 20003),
83
+ ("https", True, True, 20004), # token + roles
84
+ ("https", True, False, 20005), # token only
85
+
86
+ # mTLS configurations
87
+ ("mtls", False, False, 20006),
88
+ ("mtls", False, True, 20007), # roles only (from certificate)
89
+ ]
90
+
91
+ generated_files = []
92
+
93
+ for protocol, token, roles, port in configs:
94
+ # Create configuration name
95
+ name_parts = [protocol]
96
+ if token:
97
+ name_parts.append("token")
98
+ if roles:
99
+ name_parts.append("roles")
100
+
101
+ config_name = "_".join(name_parts)
102
+
103
+ # Create args for this configuration
104
+ config_args = args.copy()
105
+ config_args.update({
106
+ 'protocol': protocol,
107
+ 'token': token,
108
+ 'roles': roles,
109
+ 'port': port
110
+ })
111
+
112
+ # Generate configuration
113
+ config = self._create_config_from_args(config_args)
114
+
115
+ # Save configuration
116
+ config_file = self._save_config(config, config_args, config_name)
117
+ generated_files.append(config_file)
118
+
119
+ print(f"✅ Created {config_name}.json (port {port})")
120
+
121
+ # Create roles.json file if any role-based configs were generated
122
+ self._create_roles_file(args.get('output_dir', './configs'))
123
+
124
+ print(f"\n🎉 Generated {len(generated_files)} configurations in {args.get('output_dir', './configs')}/")
125
+ print("\n📋 Generated configurations:")
126
+ for config_file in generated_files:
127
+ print(f" - {config_file.name}")
128
+
129
+ return 0
130
+
131
+ def _create_config_from_args(self, args: Dict[str, Any]) -> Dict[str, Any]:
132
+ """Create configuration dictionary from arguments."""
133
+ # Start with basic configuration
134
+ config = generate_complete_config(
135
+ args.get('host', '127.0.0.1'),
136
+ args.get('port', 8000)
137
+ )
138
+
139
+ # Set protocol
140
+ config["server"]["protocol"] = args.get('protocol', 'http')
141
+
142
+ # Configure SSL based on protocol
143
+ if args.get('protocol') == 'https':
144
+ config["ssl"]["enabled"] = True
145
+ config["ssl"]["cert_file"] = f"{args.get('cert_dir', './certs')}/server.crt"
146
+ config["ssl"]["key_file"] = f"{args.get('key_dir', './keys')}/server.key"
147
+ elif args.get('protocol') == 'mtls':
148
+ config["ssl"]["enabled"] = True
149
+ config["ssl"]["cert_file"] = f"{args.get('cert_dir', './certs')}/server.crt"
150
+ config["ssl"]["key_file"] = f"{args.get('key_dir', './keys')}/server.key"
151
+ config["ssl"]["ca_cert"] = f"{args.get('cert_dir', './certs')}/ca.crt"
152
+ config["transport"]["verify_client"] = True
153
+
154
+ # Configure security if token authentication is enabled
155
+ if args.get('token'):
156
+ config["security"]["enabled"] = True
157
+ config["security"]["tokens"] = {
158
+ "admin": "admin-secret-key",
159
+ "user": "user-secret-key",
160
+ "readonly": "readonly-secret-key"
161
+ }
162
+
163
+ if args.get('roles'):
164
+ config["security"]["roles"] = {
165
+ "admin": ["read", "write", "delete", "admin"],
166
+ "user": ["read", "write"],
167
+ "readonly": ["read"]
168
+ }
169
+ config["security"]["roles_file"] = f"{args.get('output_dir', './configs')}/roles.json"
170
+ config["roles"]["enabled"] = True
171
+ config["roles"]["config_file"] = f"{args.get('output_dir', './configs')}/roles.json"
172
+ elif args.get('roles') and args.get('protocol') == 'mtls':
173
+ # For mTLS, roles can be enabled without tokens (from certificate)
174
+ config["roles"]["enabled"] = True
175
+ config["roles"]["config_file"] = f"{args.get('output_dir', './configs')}/roles.json"
176
+
177
+ # Configure proxy registration if enabled
178
+ if args.get('proxy_url'):
179
+ config["proxy_registration"]["enabled"] = True
180
+ config["proxy_registration"]["proxy_url"] = args['proxy_url']
181
+ config["proxy_registration"]["server_id"] = args.get('server_id', 'mcp-proxy-adapter')
182
+
183
+ return config
184
+
185
+ def _save_config(self, config: Dict[str, Any], args: Dict[str, Any], filename: Optional[str] = None) -> Path:
186
+ """Save configuration to file with optional validation."""
187
+ output_dir = Path(args.get('output_dir', './configs'))
188
+ output_dir.mkdir(parents=True, exist_ok=True)
189
+
190
+ # Determine filename
191
+ if filename:
192
+ config_name = filename
193
+ elif args.get('output'):
194
+ config_name = args['output']
195
+ else:
196
+ # Generate filename from arguments
197
+ name_parts = [args.get('protocol', 'http')]
198
+ if args.get('token'):
199
+ name_parts.append("token")
200
+ if args.get('roles'):
201
+ name_parts.append("roles")
202
+ config_name = "_".join(name_parts)
203
+
204
+ config_file = output_dir / f"{config_name}.json"
205
+
206
+ # Save configuration
207
+ with open(config_file, 'w', encoding='utf-8') as f:
208
+ json.dump(config, f, indent=2, ensure_ascii=False)
209
+
210
+ # Validate configuration if requested and validation is available
211
+ if not args.get('no_validate') and VALIDATION_AVAILABLE:
212
+ print(f"🔍 Validating configuration: {config_file}")
213
+ validator = ConfigValidator()
214
+ validator.config_data = config
215
+ results = validator.validate_config()
216
+
217
+ if results:
218
+ print("⚠️ Validation issues found:")
219
+ for result in results:
220
+ level_symbol = "❌" if result.level == "error" else "⚠️" if result.level == "warning" else "ℹ️"
221
+ print(f" {level_symbol} {result.message}")
222
+ if hasattr(result, 'suggestion') and result.suggestion:
223
+ print(f" Suggestion: {result.suggestion}")
224
+ else:
225
+ print("✅ Configuration validation passed!")
226
+
227
+ return config_file
228
+
229
+ def _create_roles_file(self, output_dir: str) -> None:
230
+ """Create roles.json file for role-based configurations."""
231
+ roles_config = {
232
+ "enabled": True,
233
+ "default_policy": {
234
+ "deny_by_default": False,
235
+ "require_role_match": False,
236
+ "case_sensitive": False,
237
+ "allow_wildcard": False
238
+ },
239
+ "roles": {
240
+ "admin": ["read", "write", "delete", "admin"],
241
+ "user": ["read", "write"],
242
+ "readonly": ["read"],
243
+ "guest": ["read"],
244
+ "proxy": ["read", "write"]
245
+ },
246
+ "permissions": {
247
+ "read": ["GET"],
248
+ "write": ["POST", "PUT", "PATCH"],
249
+ "delete": ["DELETE"],
250
+ "admin": ["*"]
251
+ }
252
+ }
253
+
254
+ roles_file = Path(output_dir) / "roles.json"
255
+ with open(roles_file, 'w', encoding='utf-8') as f:
256
+ json.dump(roles_config, f, indent=2, ensure_ascii=False)
257
+ print(f"✅ Created roles.json")
258
+
259
+
@@ -0,0 +1,174 @@
1
+ """
2
+ Server Command
3
+
4
+ This module implements the server command for starting MCP Proxy Adapter server.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ import json
11
+ from pathlib import Path
12
+ from typing import Dict, Any
13
+
14
+ try:
15
+ from mcp_proxy_adapter.core.validation.config_validator import ConfigValidator
16
+ from mcp_proxy_adapter.core.server_adapter import UnifiedServerRunner
17
+ from mcp_proxy_adapter.api.app import create_app
18
+ VALIDATION_AVAILABLE = True
19
+ except ImportError:
20
+ VALIDATION_AVAILABLE = False
21
+
22
+
23
+ class ServerCommand:
24
+ """Command for starting the MCP Proxy Adapter server."""
25
+
26
+ def __init__(self):
27
+ """Initialize the server command."""
28
+ pass
29
+
30
+ def execute(self, args: Dict[str, Any]) -> int:
31
+ """
32
+ Execute the server command.
33
+
34
+ Args:
35
+ args: Parsed command arguments
36
+
37
+ Returns:
38
+ Exit code (0 for success, 1 for error)
39
+ """
40
+ config_file = args['config']
41
+ no_validate = args.get('no_validate', False)
42
+
43
+ try:
44
+ # Load configuration
45
+ print(f"🔍 Loading configuration from: {config_file}")
46
+ with open(config_file, 'r', encoding='utf-8') as f:
47
+ config = json.load(f)
48
+
49
+ # Validate configuration if not disabled
50
+ if not no_validate and VALIDATION_AVAILABLE:
51
+ print("🔍 Validating configuration...")
52
+ if not self._validate_config(config, config_file):
53
+ print("❌ Configuration validation failed. Server not started.")
54
+ return 1
55
+ print("✅ Configuration validation passed!")
56
+ elif no_validate:
57
+ print("⚠️ Configuration validation skipped (--no-validate)")
58
+ else:
59
+ print("⚠️ Configuration validation not available")
60
+
61
+ # Override configuration with command line arguments
62
+ if args.get('port'):
63
+ config['server']['port'] = args['port']
64
+ print(f"🔧 Overriding port to: {args['port']}")
65
+
66
+ if args.get('host'):
67
+ config['server']['host'] = args['host']
68
+ print(f"🔧 Overriding host to: {args['host']}")
69
+
70
+ # Create and start server
71
+ print("🚀 Starting MCP Proxy Adapter server...")
72
+ self._start_server(config, args)
73
+
74
+ except FileNotFoundError:
75
+ print(f"❌ Configuration file not found: {config_file}")
76
+ return 1
77
+ except json.JSONDecodeError as e:
78
+ print(f"❌ Invalid JSON in configuration file: {e}")
79
+ return 1
80
+ except Exception as e:
81
+ print(f"❌ Error starting server: {e}")
82
+ return 1
83
+
84
+ def _validate_config(self, config: Dict[str, Any], config_file: str) -> bool:
85
+ """
86
+ Validate configuration using ConfigValidator.
87
+
88
+ Args:
89
+ config: Configuration dictionary
90
+ config_file: Path to configuration file
91
+
92
+ Returns:
93
+ True if configuration is valid, False otherwise
94
+ """
95
+ try:
96
+ validator = ConfigValidator()
97
+ validator.config_data = config
98
+ results = validator.validate_config()
99
+
100
+ # Check for errors
101
+ errors = [r for r in results if r.level == "error"]
102
+ warnings = [r for r in results if r.level == "warning"]
103
+
104
+ if errors:
105
+ print("❌ Configuration validation errors:")
106
+ for error in errors:
107
+ print(f" • {error.message}")
108
+ if hasattr(error, 'suggestion') and error.suggestion:
109
+ print(f" → {error.suggestion}")
110
+ return False
111
+
112
+ if warnings:
113
+ print("⚠️ Configuration validation warnings:")
114
+ for warning in warnings:
115
+ print(f" • {warning.message}")
116
+ if hasattr(warning, 'suggestion') and warning.suggestion:
117
+ print(f" → {warning.suggestion}")
118
+
119
+ return True
120
+
121
+ except Exception as e:
122
+ print(f"❌ Error during configuration validation: {e}")
123
+ return False
124
+
125
+ def _start_server(self, config: Dict[str, Any], args: Dict[str, Any]) -> None:
126
+ """
127
+ Start the MCP Proxy Adapter server.
128
+
129
+ Args:
130
+ config: Server configuration
131
+ args: Command line arguments
132
+ """
133
+ try:
134
+ # Create ASGI application
135
+ app = create_app(config)
136
+
137
+ # Prepare server configuration
138
+ server_config = {
139
+ 'host': config['server']['host'],
140
+ 'port': config['server']['port'],
141
+ 'log_level': config['server'].get('log_level', 'INFO'),
142
+ 'reload': args.get('reload', False)
143
+ }
144
+
145
+ # Add SSL configuration if present
146
+ if 'ssl' in config and config['ssl'].get('enabled'):
147
+ server_config.update({
148
+ 'certfile': config['ssl'].get('cert_file'),
149
+ 'keyfile': config['ssl'].get('key_file'),
150
+ 'ca_certs': config['ssl'].get('ca_cert'),
151
+ 'verify_mode': 'CERT_REQUIRED' if config.get('transport', {}).get('verify_client') else 'CERT_NONE'
152
+ })
153
+
154
+ # Start server
155
+ print(f"🌐 Server starting on {server_config['host']}:{server_config['port']}")
156
+ print(f"📋 Protocol: {config['server']['protocol']}")
157
+ print(f"🔐 Security: {'Enabled' if config.get('security', {}).get('enabled') else 'Disabled'}")
158
+ print(f"🔑 Authentication: {'Token-based' if config.get('security', {}).get('tokens') else 'Certificate-based' if config['server']['protocol'] == 'mtls' else 'None'}")
159
+ print(f"👥 Roles: {'Enabled' if config.get('roles', {}).get('enabled') else 'Disabled'}")
160
+ print("=" * 60)
161
+
162
+ # Use UnifiedServerRunner to start the server
163
+ runner = UnifiedServerRunner()
164
+ runner.run_server(app, server_config)
165
+
166
+ except ImportError as e:
167
+ print(f"❌ Missing required dependencies: {e}")
168
+ print("💡 Install required packages: pip install hypercorn")
169
+ raise
170
+ except Exception as e:
171
+ print(f"❌ Failed to start server: {e}")
172
+ raise
173
+
174
+