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,413 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Configuration Checker CLI for MCP Proxy Adapter
4
+ Validates configuration files and checks for common issues.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ import argparse
11
+ import json
12
+ import sys
13
+ import os
14
+ from pathlib import Path
15
+
16
+ # Add the project root to the path
17
+ sys.path.insert(0, str(Path(__file__).parent.parent.parent))
18
+
19
+ from mcp_proxy_adapter.config import Config
20
+
21
+
22
+ class ConfigChecker:
23
+ """Configuration checker with validation and analysis."""
24
+
25
+ def __init__(self):
26
+ self.errors: List[str] = []
27
+ self.warnings: List[str] = []
28
+ self.info: List[str] = []
29
+
30
+ def check_config_file(self, config_path: str) -> bool:
31
+ """
32
+ Check a configuration file for issues.
33
+
34
+ Args:
35
+ config_path: Path to configuration file
36
+
37
+ Returns:
38
+ True if config is valid, False otherwise
39
+ """
40
+ self.errors.clear()
41
+ self.warnings.clear()
42
+ self.info.clear()
43
+
44
+ print(f"šŸ” Checking configuration: {config_path}")
45
+ print("=" * 60)
46
+
47
+ # Check if file exists
48
+ if not os.path.exists(config_path):
49
+ self.errors.append(f"Configuration file not found: {config_path}")
50
+ return False
51
+
52
+ # Check if file is readable
53
+ if not os.access(config_path, os.R_OK):
54
+ self.errors.append(f"Configuration file is not readable: {config_path}")
55
+ return False
56
+
57
+ try:
58
+ # Load and parse JSON
59
+ with open(config_path, 'r', encoding='utf-8') as f:
60
+ config_data = json.load(f)
61
+ except json.JSONDecodeError as e:
62
+ self.errors.append(f"Invalid JSON format: {e}")
63
+ return False
64
+ except Exception as e:
65
+ self.errors.append(f"Error reading configuration file: {e}")
66
+ return False
67
+
68
+ # Load with Config class
69
+ try:
70
+ config = Config(config_path)
71
+ except Exception as e:
72
+ self.errors.append(f"Error loading configuration with Config class: {e}")
73
+ return False
74
+
75
+ # Perform checks
76
+ self._check_basic_structure(config_data)
77
+ self._check_server_config(config)
78
+ self._check_security_config(config)
79
+ self._check_ssl_config(config)
80
+ self._check_logging_config(config)
81
+ self._check_file_paths(config_path, config)
82
+ self._check_port_availability(config)
83
+
84
+ # Print results
85
+ self._print_results()
86
+
87
+ return len(self.errors) == 0
88
+
89
+ def _check_basic_structure(self, config_data: Dict[str, Any]) -> None:
90
+ """Check basic configuration structure."""
91
+ required_sections = ["server", "security", "logging", "transport"]
92
+
93
+ for section in required_sections:
94
+ if section not in config_data:
95
+ self.errors.append(f"Missing required section: {section}")
96
+ else:
97
+ self.info.append(f"āœ… Section '{section}' present")
98
+
99
+ def _check_server_config(self, config: Config) -> None:
100
+ """Check server configuration."""
101
+ protocol = config.get("server.protocol")
102
+ host = config.get("server.host")
103
+ port = config.get("server.port")
104
+
105
+ if not protocol:
106
+ self.errors.append("Server protocol not specified")
107
+ elif protocol not in ["http", "https", "mtls"]:
108
+ self.errors.append(f"Invalid server protocol: {protocol}")
109
+ else:
110
+ self.info.append(f"āœ… Server protocol: {protocol}")
111
+
112
+ if not host:
113
+ self.warnings.append("Server host not specified, using default")
114
+ else:
115
+ self.info.append(f"āœ… Server host: {host}")
116
+
117
+ if not port:
118
+ self.errors.append("Server port not specified")
119
+ elif not isinstance(port, int) or port < 1 or port > 65535:
120
+ self.errors.append(f"Invalid server port: {port}")
121
+ else:
122
+ self.info.append(f"āœ… Server port: {port}")
123
+
124
+ def _check_security_config(self, config: Config) -> None:
125
+ """Check security configuration."""
126
+ security_enabled = config.get("security.enabled", False)
127
+ tokens = config.get("security.tokens", {})
128
+ roles = config.get("security.roles", {})
129
+ roles_file = config.get("security.roles_file")
130
+
131
+ if security_enabled:
132
+ self.info.append("āœ… Security enabled")
133
+
134
+ if not tokens and not roles and not roles_file:
135
+ self.warnings.append("Security enabled but no authentication methods configured")
136
+ else:
137
+ if tokens:
138
+ self.info.append(f"āœ… Tokens configured: {len(tokens)} tokens")
139
+ if roles:
140
+ self.info.append(f"āœ… Roles configured: {len(roles)} roles")
141
+ if roles_file:
142
+ self.info.append(f"āœ… Roles file: {roles_file}")
143
+ else:
144
+ self.info.append("ā„¹ļø Security disabled")
145
+
146
+ def _check_ssl_config(self, config: Config) -> None:
147
+ """Check SSL configuration."""
148
+ protocol = config.get("server.protocol")
149
+ chk_hostname = config.get("transport.ssl.chk_hostname")
150
+
151
+ if protocol in ["https", "mtls"]:
152
+ self.info.append(f"āœ… SSL protocol: {protocol}")
153
+
154
+ if chk_hostname is None:
155
+ self.warnings.append("chk_hostname not specified for SSL protocol")
156
+ elif chk_hostname:
157
+ self.info.append("āœ… Hostname checking enabled")
158
+ else:
159
+ self.warnings.append("Hostname checking disabled for SSL protocol")
160
+ else:
161
+ if chk_hostname:
162
+ self.warnings.append("Hostname checking enabled for non-SSL protocol")
163
+ else:
164
+ self.info.append("āœ… Hostname checking disabled for HTTP")
165
+
166
+ def _check_logging_config(self, config: Config) -> None:
167
+ """Check logging configuration."""
168
+ log_level = config.get("logging.level")
169
+ log_file = config.get("logging.file")
170
+ log_dir = config.get("logging.log_dir")
171
+
172
+ if log_level and log_level.upper() in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
173
+ self.info.append(f"āœ… Log level: {log_level}")
174
+ else:
175
+ self.warnings.append(f"Invalid or missing log level: {log_level}")
176
+
177
+ if log_file:
178
+ self.info.append(f"āœ… Log file: {log_file}")
179
+
180
+ if log_dir:
181
+ self.info.append(f"āœ… Log directory: {log_dir}")
182
+
183
+ def _check_file_paths(self, config_path: str, config: Config) -> None:
184
+ """Check file paths in configuration."""
185
+ config_dir = Path(config_path).parent
186
+
187
+ # Check roles file
188
+ roles_file = config.get("security.roles_file")
189
+ if roles_file:
190
+ roles_path = config_dir / roles_file
191
+ if not roles_path.exists():
192
+ self.warnings.append(f"Roles file not found: {roles_path}")
193
+ else:
194
+ self.info.append(f"āœ… Roles file exists: {roles_path}")
195
+
196
+ # Check log directory
197
+ log_dir = config.get("logging.log_dir")
198
+ if log_dir:
199
+ log_path = config_dir / log_dir
200
+ if not log_path.exists():
201
+ self.warnings.append(f"Log directory not found: {log_path}")
202
+ else:
203
+ self.info.append(f"āœ… Log directory exists: {log_path}")
204
+
205
+ def _check_port_availability(self, config: Config) -> None:
206
+ """Check if the configured port is available."""
207
+ import socket
208
+
209
+ port = config.get("server.port")
210
+ if not port:
211
+ return
212
+
213
+ try:
214
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
215
+ s.bind(('localhost', port))
216
+ self.info.append(f"āœ… Port {port} is available")
217
+ except OSError:
218
+ self.warnings.append(f"Port {port} is already in use")
219
+
220
+ def _print_results(self) -> None:
221
+ """Print check results."""
222
+ if self.info:
223
+ print("\nšŸ“‹ Information:")
224
+ for info in self.info:
225
+ print(f" {info}")
226
+
227
+ if self.warnings:
228
+ print("\nāš ļø Warnings:")
229
+ for warning in self.warnings:
230
+ print(f" {warning}")
231
+
232
+ if self.errors:
233
+ print("\nāŒ Errors:")
234
+ for error in self.errors:
235
+ print(f" {error}")
236
+
237
+ print(f"\nšŸ“Š Summary:")
238
+ print(f" Information: {len(self.info)}")
239
+ print(f" Warnings: {len(self.warnings)}")
240
+ print(f" Errors: {len(self.errors)}")
241
+
242
+ if self.errors:
243
+ print(f" Status: āŒ FAILED")
244
+ elif self.warnings:
245
+ print(f" Status: āš ļø WARNINGS")
246
+ else:
247
+ print(f" Status: āœ… PASSED")
248
+
249
+
250
+ def check_all_configs(config_dir: str = "./configs") -> None:
251
+ """Check all configuration files in a directory."""
252
+ config_dir_path = Path(config_dir)
253
+
254
+ if not config_dir_path.exists():
255
+ print(f"āŒ Configuration directory not found: {config_dir}")
256
+ return
257
+
258
+ config_files = list(config_dir_path.glob("*.json"))
259
+
260
+ if not config_files:
261
+ print(f"āŒ No JSON configuration files found in: {config_dir}")
262
+ return
263
+
264
+ print(f"šŸ” Checking {len(config_files)} configuration files in {config_dir}")
265
+ print("=" * 80)
266
+
267
+ checker = ConfigChecker()
268
+ total_checked = 0
269
+ total_passed = 0
270
+
271
+ for config_file in sorted(config_files):
272
+ if checker.check_config_file(str(config_file)):
273
+ total_passed += 1
274
+ total_checked += 1
275
+ print("\n" + "-" * 80 + "\n")
276
+
277
+ print(f"šŸ“Š Final Summary:")
278
+ print(f" Total files checked: {total_checked}")
279
+ print(f" Passed: {total_passed}")
280
+ print(f" Failed: {total_checked - total_passed}")
281
+ print(f" Success rate: {(total_passed / total_checked * 100):.1f}%")
282
+
283
+
284
+ def validate_config_syntax(config_path: str) -> bool:
285
+ """Validate configuration syntax only."""
286
+ try:
287
+ with open(config_path, 'r', encoding='utf-8') as f:
288
+ json.load(f)
289
+ print(f"āœ… Configuration syntax is valid: {config_path}")
290
+ return True
291
+ except json.JSONDecodeError as e:
292
+ print(f"āŒ Invalid JSON syntax: {e}")
293
+ return False
294
+ except Exception as e:
295
+ print(f"āŒ Error reading file: {e}")
296
+ return False
297
+
298
+
299
+ def compare_configs(config1_path: str, config2_path: str) -> None:
300
+ """Compare two configuration files."""
301
+ print(f"šŸ” Comparing configurations:")
302
+ print(f" Config 1: {config1_path}")
303
+ print(f" Config 2: {config2_path}")
304
+ print("=" * 60)
305
+
306
+ try:
307
+ with open(config1_path, 'r') as f:
308
+ config1 = json.load(f)
309
+ with open(config2_path, 'r') as f:
310
+ config2 = json.load(f)
311
+ except Exception as e:
312
+ print(f"āŒ Error loading configurations: {e}")
313
+ return
314
+
315
+ # Compare key sections
316
+ sections_to_compare = ["server", "security", "logging", "transport"]
317
+
318
+ for section in sections_to_compare:
319
+ print(f"\nšŸ“‹ Section: {section}")
320
+
321
+ if section not in config1 and section not in config2:
322
+ print(" Both configs missing this section")
323
+ continue
324
+ elif section not in config1:
325
+ print(f" āŒ Missing in {config1_path}")
326
+ continue
327
+ elif section not in config2:
328
+ print(f" āŒ Missing in {config2_path}")
329
+ continue
330
+
331
+ if config1[section] == config2[section]:
332
+ print(" āœ… Identical")
333
+ else:
334
+ print(" āš ļø Different")
335
+ # Show differences for key fields
336
+ if section == "server":
337
+ for key in ["protocol", "host", "port"]:
338
+ val1 = config1[section].get(key)
339
+ val2 = config2[section].get(key)
340
+ if val1 != val2:
341
+ print(f" {key}: {val1} vs {val2}")
342
+
343
+
344
+ def main():
345
+ """Main CLI function."""
346
+ parser = argparse.ArgumentParser(
347
+ description="MCP Proxy Adapter Configuration Checker",
348
+ formatter_class=argparse.RawDescriptionHelpFormatter,
349
+ epilog="""
350
+ Examples:
351
+ # Check a single configuration file
352
+ python check_config.py configs/http.json
353
+
354
+ # Check all configurations in a directory
355
+ python check_config.py --all
356
+
357
+ # Validate JSON syntax only
358
+ python check_config.py --syntax configs/http.json
359
+
360
+ # Compare two configurations
361
+ python check_config.py --compare configs/http.json configs/https.json
362
+ """
363
+ )
364
+
365
+ parser.add_argument(
366
+ "config_file",
367
+ nargs="?",
368
+ help="Configuration file to check"
369
+ )
370
+
371
+ parser.add_argument(
372
+ "--all",
373
+ action="store_true",
374
+ help="Check all configuration files in ./configs directory"
375
+ )
376
+
377
+ parser.add_argument(
378
+ "--syntax",
379
+ action="store_true",
380
+ help="Validate JSON syntax only"
381
+ )
382
+
383
+ parser.add_argument(
384
+ "--compare",
385
+ nargs=2,
386
+ metavar=("CONFIG1", "CONFIG2"),
387
+ help="Compare two configuration files"
388
+ )
389
+
390
+ parser.add_argument(
391
+ "--config-dir",
392
+ default="./configs",
393
+ help="Configuration directory (default: ./configs)"
394
+ )
395
+
396
+ args = parser.parse_args()
397
+
398
+ if args.compare:
399
+ compare_configs(args.compare[0], args.compare[1])
400
+ elif args.all:
401
+ check_all_configs(args.config_dir)
402
+ elif args.config_file:
403
+ if args.syntax:
404
+ validate_config_syntax(args.config_file)
405
+ else:
406
+ checker = ConfigChecker()
407
+ checker.check_config_file(args.config_file)
408
+ else:
409
+ parser.print_help()
410
+
411
+
412
+ if __name__ == "__main__":
413
+ main()
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Author: Vasiliy Zdanovskiy
4
+ email: vasilyvz@gmail.com
5
+
6
+ Example of using JsonRpcClient library for MCP Proxy Adapter.
7
+
8
+ This example demonstrates:
9
+ - Basic client initialization
10
+ - Using built-in commands (echo, help, long_task, job_status)
11
+ - Using queue management commands (queue_add_job, queue_start_job, etc.)
12
+ - Error handling
13
+
14
+ Usage:
15
+ # Make sure server is running, then:
16
+ python -m mcp_proxy_adapter.examples.client_usage_example
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import json
22
+ import time
23
+ import uuid
24
+
25
+ from mcp_proxy_adapter.client.jsonrpc_client import JsonRpcClient
26
+
27
+
28
+ def example_builtin_commands(client: JsonRpcClient) -> None:
29
+ """Example of using built-in commands."""
30
+ print("\n" + "=" * 60)
31
+ print("šŸ“‹ Example: Built-in Commands")
32
+ print("=" * 60)
33
+
34
+ # Echo command
35
+ print("\n1. Echo command:")
36
+ result = client.echo(message="Hello from client!")
37
+ print(f" Result: {json.dumps(result, ensure_ascii=False, indent=2)}")
38
+
39
+ # Help command
40
+ print("\n2. Help command:")
41
+ result = client.help()
42
+ print(f" Commands available: {len(result.get('data', {}).get('commands', []))}")
43
+
44
+ # Long task
45
+ print("\n3. Starting long task (5 seconds):")
46
+ result = client.long_task(seconds=5)
47
+ job_id = result.get("data", {}).get("job_id")
48
+ print(f" Job ID: {job_id}")
49
+
50
+ # Check job status
51
+ print("\n4. Checking job status:")
52
+ time.sleep(2)
53
+ result = client.job_status(job_id=job_id)
54
+ print(f" Status: {json.dumps(result, ensure_ascii=False, indent=2)}")
55
+
56
+ # Wait for completion
57
+ print("\n5. Waiting for task completion...")
58
+ time.sleep(4)
59
+ result = client.job_status(job_id=job_id)
60
+ status = result.get("data", {}).get("status")
61
+ print(f" Final status: {status}")
62
+
63
+
64
+ def example_queue_commands(client: JsonRpcClient) -> None:
65
+ """Example of using queue management commands."""
66
+ print("\n" + "=" * 60)
67
+ print("šŸ“‹ Example: Queue Management Commands")
68
+ print("=" * 60)
69
+
70
+ job_id = f"example-{uuid.uuid4().hex[:8]}"
71
+
72
+ # Queue health
73
+ print("\n1. Queue health:")
74
+ try:
75
+ result = client.queue_health()
76
+ print(f" Result: {json.dumps(result, ensure_ascii=False, indent=2)}")
77
+ except RuntimeError as e:
78
+ print(f" āš ļø Queue commands not available: {e}")
79
+ return
80
+
81
+ # Add job
82
+ print(f"\n2. Adding job (job_id={job_id}):")
83
+ result = client.queue_add_job(
84
+ job_type="long_running",
85
+ job_id=job_id,
86
+ params={"duration": 5, "task_type": "example_task"},
87
+ )
88
+ print(f" Result: {json.dumps(result, ensure_ascii=False, indent=2)}")
89
+
90
+ # Get job status (should be pending)
91
+ print("\n3. Getting job status (should be pending):")
92
+ result = client.queue_get_job_status(job_id=job_id)
93
+ print(f" Status: {json.dumps(result, ensure_ascii=False, indent=2)}")
94
+
95
+ # List jobs
96
+ print("\n4. Listing all jobs:")
97
+ result = client.queue_list_jobs()
98
+ print(f" Jobs count: {len(result.get('data', {}).get('jobs', []))}")
99
+
100
+ # Start job
101
+ print("\n5. Starting job:")
102
+ result = client.queue_start_job(job_id=job_id)
103
+ print(f" Result: {json.dumps(result, ensure_ascii=False, indent=2)}")
104
+
105
+ # Check status (should be running)
106
+ print("\n6. Checking status (should be running):")
107
+ time.sleep(1)
108
+ result = client.queue_get_job_status(job_id=job_id)
109
+ print(f" Status: {json.dumps(result, ensure_ascii=False, indent=2)}")
110
+
111
+ # Wait for completion
112
+ print("\n7. Waiting for job completion...")
113
+ time.sleep(6)
114
+ result = client.queue_get_job_status(job_id=job_id)
115
+ status = result.get("data", {}).get("status")
116
+ print(f" Final status: {status}")
117
+
118
+ # Delete job
119
+ print("\n8. Deleting job:")
120
+ result = client.queue_delete_job(job_id=job_id)
121
+ print(f" Result: {json.dumps(result, ensure_ascii=False, indent=2)}")
122
+
123
+
124
+ def main() -> None:
125
+ """Main example function."""
126
+ print("šŸš€ JsonRpcClient Usage Example")
127
+ print("=" * 60)
128
+
129
+ # Initialize client (adjust protocol, host, port as needed)
130
+ client = JsonRpcClient(
131
+ protocol="http",
132
+ host="127.0.0.1",
133
+ port=8080,
134
+ )
135
+
136
+ # Check server health
137
+ print("\nšŸ“” Checking server health...")
138
+ try:
139
+ health = client.health()
140
+ print(f"āœ… Server is healthy: {json.dumps(health, ensure_ascii=False)}")
141
+ except Exception as e:
142
+ print(f"āŒ Server is not available: {e}")
143
+ print(" Make sure the server is running on http://127.0.0.1:8080")
144
+ return
145
+
146
+ # Run examples
147
+ try:
148
+ example_builtin_commands(client)
149
+ except Exception as e:
150
+ print(f"\nāŒ Error in built-in commands example: {e}")
151
+
152
+ try:
153
+ example_queue_commands(client)
154
+ except Exception as e:
155
+ print(f"\nāŒ Error in queue commands example: {e}")
156
+
157
+ print("\n" + "=" * 60)
158
+ print("āœ… Examples completed")
159
+ print("=" * 60)
160
+
161
+
162
+ if __name__ == "__main__":
163
+ main()
164
+
@@ -0,0 +1,5 @@
1
+ """Example Commands Package.
2
+
3
+ This package contains example command implementations demonstrating
4
+ various patterns for creating custom commands in MCP Proxy Adapter.
5
+ """