mcp-proxy-adapter 6.9.28__py3-none-any.whl → 6.9.29__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 (212) hide show
  1. mcp_proxy_adapter/__init__.py +10 -0
  2. mcp_proxy_adapter/__main__.py +8 -21
  3. mcp_proxy_adapter/api/app.py +10 -913
  4. mcp_proxy_adapter/api/core/__init__.py +18 -0
  5. mcp_proxy_adapter/api/core/app_factory.py +243 -0
  6. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  7. mcp_proxy_adapter/api/core/registration_manager.py +166 -0
  8. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  9. mcp_proxy_adapter/api/handlers.py +78 -199
  10. mcp_proxy_adapter/api/middleware/__init__.py +1 -44
  11. mcp_proxy_adapter/api/middleware/base.py +0 -42
  12. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -85
  13. mcp_proxy_adapter/api/middleware/error_handling.py +1 -127
  14. mcp_proxy_adapter/api/middleware/factory.py +0 -94
  15. mcp_proxy_adapter/api/middleware/logging.py +0 -112
  16. mcp_proxy_adapter/api/middleware/performance.py +0 -35
  17. mcp_proxy_adapter/api/middleware/protocol_middleware.py +2 -98
  18. mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -37
  19. mcp_proxy_adapter/api/middleware/unified_security.py +10 -10
  20. mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -118
  21. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  22. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  23. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  24. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  25. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  26. mcp_proxy_adapter/api/schemas.py +0 -61
  27. mcp_proxy_adapter/api/tool_integration.py +0 -117
  28. mcp_proxy_adapter/api/tools.py +0 -46
  29. mcp_proxy_adapter/cli/__init__.py +12 -0
  30. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  31. mcp_proxy_adapter/cli/commands/client.py +100 -0
  32. mcp_proxy_adapter/cli/commands/config_generate.py +21 -0
  33. mcp_proxy_adapter/cli/commands/config_validate.py +36 -0
  34. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  35. mcp_proxy_adapter/cli/commands/server.py +174 -0
  36. mcp_proxy_adapter/cli/commands/sets.py +128 -0
  37. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  38. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  39. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  40. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  41. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  42. mcp_proxy_adapter/cli/main.py +63 -0
  43. mcp_proxy_adapter/cli/parser.py +324 -0
  44. mcp_proxy_adapter/cli/validators.py +231 -0
  45. mcp_proxy_adapter/client/jsonrpc_client.py +406 -0
  46. mcp_proxy_adapter/client/proxy.py +45 -0
  47. mcp_proxy_adapter/commands/__init__.py +44 -28
  48. mcp_proxy_adapter/commands/auth_validation_command.py +7 -344
  49. mcp_proxy_adapter/commands/base.py +19 -43
  50. mcp_proxy_adapter/commands/builtin_commands.py +0 -75
  51. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  52. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  53. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  54. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  55. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  56. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  57. mcp_proxy_adapter/commands/catalog_manager.py +58 -928
  58. mcp_proxy_adapter/commands/cert_monitor_command.py +0 -88
  59. mcp_proxy_adapter/commands/certificate_management_command.py +0 -45
  60. mcp_proxy_adapter/commands/command_registry.py +172 -904
  61. mcp_proxy_adapter/commands/config_command.py +0 -28
  62. mcp_proxy_adapter/commands/dependency_container.py +1 -70
  63. mcp_proxy_adapter/commands/dependency_manager.py +0 -128
  64. mcp_proxy_adapter/commands/echo_command.py +0 -34
  65. mcp_proxy_adapter/commands/health_command.py +0 -3
  66. mcp_proxy_adapter/commands/help_command.py +0 -159
  67. mcp_proxy_adapter/commands/hooks.py +0 -137
  68. mcp_proxy_adapter/commands/key_management_command.py +0 -25
  69. mcp_proxy_adapter/commands/load_command.py +7 -78
  70. mcp_proxy_adapter/commands/plugins_command.py +0 -16
  71. mcp_proxy_adapter/commands/protocol_management_command.py +0 -28
  72. mcp_proxy_adapter/commands/proxy_registration_command.py +0 -88
  73. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  74. mcp_proxy_adapter/commands/registration_status_command.py +0 -43
  75. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  76. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  77. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  78. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  79. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  80. mcp_proxy_adapter/commands/reload_command.py +0 -80
  81. mcp_proxy_adapter/commands/result.py +25 -77
  82. mcp_proxy_adapter/commands/role_test_command.py +0 -44
  83. mcp_proxy_adapter/commands/roles_management_command.py +0 -199
  84. mcp_proxy_adapter/commands/security_command.py +0 -30
  85. mcp_proxy_adapter/commands/settings_command.py +0 -68
  86. mcp_proxy_adapter/commands/ssl_setup_command.py +0 -42
  87. mcp_proxy_adapter/commands/token_management_command.py +0 -1
  88. mcp_proxy_adapter/commands/transport_management_command.py +0 -20
  89. mcp_proxy_adapter/commands/unload_command.py +0 -71
  90. mcp_proxy_adapter/config.py +15 -626
  91. mcp_proxy_adapter/core/__init__.py +5 -39
  92. mcp_proxy_adapter/core/app_factory.py +14 -36
  93. mcp_proxy_adapter/core/app_runner.py +0 -27
  94. mcp_proxy_adapter/core/auth_validator.py +1 -93
  95. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  96. mcp_proxy_adapter/core/certificate/certificate_creator.py +371 -0
  97. mcp_proxy_adapter/core/certificate/certificate_extractor.py +183 -0
  98. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  99. mcp_proxy_adapter/core/certificate/certificate_validator.py +110 -0
  100. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +70 -0
  101. mcp_proxy_adapter/core/certificate_utils.py +64 -903
  102. mcp_proxy_adapter/core/client.py +0 -6
  103. mcp_proxy_adapter/core/client_manager.py +0 -19
  104. mcp_proxy_adapter/core/client_security.py +0 -2
  105. mcp_proxy_adapter/core/config/__init__.py +18 -0
  106. mcp_proxy_adapter/core/config/config.py +195 -0
  107. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  108. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  109. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  110. mcp_proxy_adapter/core/config/simple_config.py +112 -0
  111. mcp_proxy_adapter/core/config/simple_config_generator.py +50 -0
  112. mcp_proxy_adapter/core/config/simple_config_validator.py +96 -0
  113. mcp_proxy_adapter/core/config_converter.py +0 -186
  114. mcp_proxy_adapter/core/config_validator.py +96 -1238
  115. mcp_proxy_adapter/core/errors.py +7 -42
  116. mcp_proxy_adapter/core/job_manager.py +54 -0
  117. mcp_proxy_adapter/core/logging.py +2 -22
  118. mcp_proxy_adapter/core/mtls_asgi.py +0 -20
  119. mcp_proxy_adapter/core/mtls_asgi_app.py +0 -12
  120. mcp_proxy_adapter/core/mtls_proxy.py +0 -80
  121. mcp_proxy_adapter/core/mtls_server.py +3 -173
  122. mcp_proxy_adapter/core/protocol_manager.py +1 -191
  123. mcp_proxy_adapter/core/proxy/__init__.py +22 -0
  124. mcp_proxy_adapter/core/proxy/auth_manager.py +27 -0
  125. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +137 -0
  126. mcp_proxy_adapter/core/proxy/registration_client.py +60 -0
  127. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  128. mcp_proxy_adapter/core/proxy_client.py +0 -1
  129. mcp_proxy_adapter/core/proxy_registration.py +36 -913
  130. mcp_proxy_adapter/core/role_utils.py +0 -308
  131. mcp_proxy_adapter/core/security_adapter.py +1 -36
  132. mcp_proxy_adapter/core/security_factory.py +1 -150
  133. mcp_proxy_adapter/core/security_integration.py +0 -33
  134. mcp_proxy_adapter/core/server_adapter.py +1 -40
  135. mcp_proxy_adapter/core/server_engine.py +2 -173
  136. mcp_proxy_adapter/core/settings.py +0 -127
  137. mcp_proxy_adapter/core/signal_handler.py +0 -65
  138. mcp_proxy_adapter/core/ssl_utils.py +19 -137
  139. mcp_proxy_adapter/core/transport_manager.py +0 -151
  140. mcp_proxy_adapter/core/unified_config_adapter.py +1 -193
  141. mcp_proxy_adapter/core/utils.py +1 -182
  142. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  143. mcp_proxy_adapter/core/validation/config_validator.py +211 -0
  144. mcp_proxy_adapter/core/validation/file_validator.py +73 -0
  145. mcp_proxy_adapter/core/validation/protocol_validator.py +191 -0
  146. mcp_proxy_adapter/core/validation/security_validator.py +58 -0
  147. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  148. mcp_proxy_adapter/custom_openapi.py +33 -652
  149. mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -23
  150. mcp_proxy_adapter/examples/check_config.py +0 -2
  151. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  152. mcp_proxy_adapter/examples/config_builder.py +13 -2
  153. mcp_proxy_adapter/examples/config_cli.py +0 -1
  154. mcp_proxy_adapter/examples/create_test_configs.py +0 -46
  155. mcp_proxy_adapter/examples/debug_request_state.py +0 -1
  156. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -47
  157. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -45
  158. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +0 -12
  159. mcp_proxy_adapter/examples/full_application/commands/help_command.py +0 -12
  160. mcp_proxy_adapter/examples/full_application/commands/list_command.py +0 -7
  161. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -2
  162. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -59
  163. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -54
  164. mcp_proxy_adapter/examples/full_application/main.py +186 -150
  165. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -107
  166. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +0 -24
  167. mcp_proxy_adapter/examples/full_application/test_server.py +0 -58
  168. mcp_proxy_adapter/examples/generate_config.py +65 -11
  169. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  170. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  171. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  172. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  173. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  174. mcp_proxy_adapter/examples/required_certificates.py +0 -2
  175. mcp_proxy_adapter/examples/run_full_test_suite.py +0 -29
  176. mcp_proxy_adapter/examples/run_proxy_server.py +31 -71
  177. mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -27
  178. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  179. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  180. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  181. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  182. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  183. mcp_proxy_adapter/examples/security_test_client.py +24 -1075
  184. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  185. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  186. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  187. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  188. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  189. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  190. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  191. mcp_proxy_adapter/examples/setup_test_environment.py +133 -1425
  192. mcp_proxy_adapter/examples/test_config.py +0 -3
  193. mcp_proxy_adapter/examples/test_config_builder.py +25 -405
  194. mcp_proxy_adapter/examples/test_examples.py +0 -1
  195. mcp_proxy_adapter/examples/test_framework_complete.py +0 -2
  196. mcp_proxy_adapter/examples/test_mcp_server.py +0 -1
  197. mcp_proxy_adapter/examples/test_protocol_examples.py +0 -1
  198. mcp_proxy_adapter/examples/universal_client.py +0 -6
  199. mcp_proxy_adapter/examples/update_config_certificates.py +0 -1
  200. mcp_proxy_adapter/examples/validate_generator_compatibility.py +0 -1
  201. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +0 -187
  202. mcp_proxy_adapter/integrations/__init__.py +25 -0
  203. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  204. mcp_proxy_adapter/main.py +70 -62
  205. mcp_proxy_adapter/openapi.py +0 -22
  206. mcp_proxy_adapter/version.py +1 -1
  207. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/METADATA +2 -1
  208. mcp_proxy_adapter-6.9.29.dist-info/RECORD +235 -0
  209. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/entry_points.txt +1 -1
  210. mcp_proxy_adapter-6.9.28.dist-info/RECORD +0 -149
  211. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/WHEEL +0 -0
  212. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,128 @@
1
+ """
2
+ Sets Command
3
+
4
+ This module implements the sets command for generating configurations using predefined sets.
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
+ from mcp_proxy_adapter.core.config.simple_config import (
15
+ SimpleConfig,
16
+ SimpleConfigModel,
17
+ ServerConfig,
18
+ ProxyClientConfig,
19
+ AuthConfig,
20
+ )
21
+
22
+
23
+ class SetsCommand:
24
+ """Command for generating configurations using predefined sets."""
25
+
26
+ def __init__(self):
27
+ """Initialize the sets command."""
28
+ pass
29
+
30
+ def execute(self, args: Dict[str, Any]) -> int:
31
+ """
32
+ Execute the sets command.
33
+
34
+ Args:
35
+ args: Parsed command arguments
36
+
37
+ Returns:
38
+ Exit code (0 for success, 1 for error)
39
+ """
40
+ set_name = args.get('set_name')
41
+
42
+ if not set_name:
43
+ print("❌ No set specified. Use: sets {http,https,mtls}")
44
+ return 1
45
+
46
+ try:
47
+ # Generate configuration based on set
48
+ config_path = self._create_config_from_set(set_name, args)
49
+
50
+ print(f"✅ {set_name.upper()} configuration saved to: {config_path}")
51
+ return 0
52
+
53
+ except Exception as e:
54
+ print(f"❌ Error generating {set_name} configuration: {e}")
55
+ return 1
56
+
57
+ def _create_config_from_set(self, set_name: str, args: Dict[str, Any]) -> Path:
58
+ """
59
+ Create configuration based on the specified set.
60
+
61
+ Args:
62
+ set_name: Name of the configuration set
63
+ args: Command arguments
64
+
65
+ Returns:
66
+ Path to saved configuration file
67
+ """
68
+ host = args.get('host', '127.0.0.1')
69
+ port = int(args.get('port', 8000))
70
+ protocol = set_name
71
+
72
+ # Build server config compatible with SimpleConfig
73
+ server = ServerConfig(host=host, port=port, protocol=protocol)
74
+ cert_dir = Path(args.get('cert_dir') or './certs')
75
+ key_dir = Path(args.get('key_dir') or './keys')
76
+ if protocol in ('https', 'mtls'):
77
+ # Prefer test-server.* filenames if present, otherwise fallback to server.*
78
+ cert_file = cert_dir / 'test-server.crt'
79
+ key_file = key_dir / 'test-server.key'
80
+ if not cert_file.exists():
81
+ cert_file = cert_dir / 'server.crt'
82
+ if not key_file.exists():
83
+ key_file = key_dir / 'server.key'
84
+ server.cert_file = str(cert_file)
85
+ server.key_file = str(key_file)
86
+ if protocol == 'mtls':
87
+ # CA file path is expected by validator; try ca/ca.crt relative to provided cert_dir
88
+ ca_candidate = cert_dir.parent / 'ca' / 'ca.crt'
89
+ if not ca_candidate.exists():
90
+ ca_candidate = cert_dir / 'ca.crt'
91
+ server.ca_cert_file = str(ca_candidate)
92
+
93
+ # Proxy client (disabled by default here)
94
+ proxy = ProxyClientConfig(enabled=False)
95
+
96
+ # Auth config based on modifiers
97
+ use_token = 'token' in (args.get('modifiers') or []) or bool(args.get('token'))
98
+ use_roles = 'roles' in (args.get('modifiers') or []) or bool(args.get('roles'))
99
+ # If roles are requested, token must be enabled to satisfy validator
100
+ if use_roles and not use_token:
101
+ use_token = True
102
+ tokens = {
103
+ 'admin': ['read', 'write', 'delete', 'admin'],
104
+ } if use_token else {}
105
+ roles = {
106
+ 'admin': ['read', 'write', 'delete', 'admin'],
107
+ 'user': ['read', 'write'],
108
+ } if use_roles else {}
109
+ auth = AuthConfig(use_token=use_token, use_roles=use_roles, tokens=tokens, roles=roles)
110
+
111
+ # Save using SimpleConfig
112
+ model = SimpleConfigModel(server=server, proxy_client=proxy, auth=auth)
113
+ out_dir = Path(args.get('output_dir', './configs'))
114
+ out_dir.mkdir(parents=True, exist_ok=True)
115
+ name_parts = [set_name]
116
+ if use_token and set_name in ['http', 'https']:
117
+ name_parts.append('token')
118
+ if use_roles:
119
+ name_parts.append('roles')
120
+ filename = args.get('output') or "_".join(name_parts)
121
+ out_path = out_dir / f"{filename}.json"
122
+
123
+ cfg = SimpleConfig(str(out_path))
124
+ cfg.model = model
125
+ cfg.save()
126
+ return out_path
127
+
128
+
@@ -0,0 +1,177 @@
1
+ """
2
+ TestConfig Command
3
+
4
+ This module implements the testconfig command for validating configuration files.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ import json
11
+ from typing import Dict, Any
12
+
13
+ try:
14
+ from mcp_proxy_adapter.core.config_validator import ConfigValidator
15
+ VALIDATION_AVAILABLE = True
16
+ except ImportError:
17
+ VALIDATION_AVAILABLE = False
18
+
19
+
20
+ class TestConfigCommand:
21
+ """Command for testing and validating configuration files."""
22
+
23
+ def __init__(self):
24
+ """Initialize the testconfig command."""
25
+ pass
26
+
27
+ def execute(self, args: Dict[str, Any]) -> int:
28
+ """
29
+ Execute the testconfig command.
30
+
31
+ Args:
32
+ args: Parsed command arguments
33
+
34
+ Returns:
35
+ Exit code (0 for success, 1 for error)
36
+ """
37
+ if not VALIDATION_AVAILABLE:
38
+ print("❌ Configuration validation not available. Install the package to enable validation.")
39
+ return 1
40
+
41
+ config_file = args['config']
42
+ verbose = args.get('verbose', False)
43
+ fix_suggestions = args.get('fix_suggestions', False)
44
+ json_output = args.get('json', False)
45
+
46
+ try:
47
+ # Load and validate configuration
48
+ validator = ConfigValidator(config_file)
49
+ validator.load_config()
50
+ results = validator.validate_config()
51
+
52
+ # Get validation summary
53
+ summary = validator.get_validation_summary()
54
+
55
+ if json_output:
56
+ # Output results in JSON format
57
+ self._output_json_results(summary, results, config_file)
58
+ else:
59
+ # Output human-readable results
60
+ self._output_human_results(summary, results, config_file, verbose, fix_suggestions)
61
+
62
+ # Return appropriate exit code
63
+ return 0 if summary['is_valid'] else 1
64
+
65
+ except Exception as e:
66
+ print(f"❌ Error testing configuration: {e}")
67
+ return 1
68
+
69
+ def _output_json_results(self, summary: Dict[str, Any], results: list, config_file: str) -> None:
70
+ """Output validation results in JSON format."""
71
+ output = {
72
+ "config_file": config_file,
73
+ "summary": summary,
74
+ "issues": []
75
+ }
76
+
77
+ for result in results:
78
+ issue = {
79
+ "level": result.level,
80
+ "message": result.message,
81
+ "section": result.section,
82
+ "key": result.key if hasattr(result, 'key') else None,
83
+ "suggestion": result.suggestion if hasattr(result, 'suggestion') else None
84
+ }
85
+ output["issues"].append(issue)
86
+
87
+ print(json.dumps(output, indent=2, ensure_ascii=False))
88
+
89
+ def _output_human_results(self, summary: Dict[str, Any], results: list, config_file: str,
90
+ verbose: bool, fix_suggestions: bool) -> None:
91
+ """Output validation results in human-readable format."""
92
+ print("=" * 60)
93
+ print("CONFIGURATION VALIDATION REPORT")
94
+ print("=" * 60)
95
+ print(f"Configuration file: {config_file}")
96
+ print(f"Total issues: {summary['total_issues']}")
97
+ print(f"Errors: {summary['errors']}")
98
+ print(f"Warnings: {summary['warnings']}")
99
+ print(f"Info: {summary['info']}")
100
+ print(f"Configuration is valid: {'✅ YES' if summary['is_valid'] else '❌ NO'}")
101
+ print("=" * 60)
102
+
103
+ if results:
104
+ print("\n📋 DETAILED ISSUES:")
105
+ print("-" * 40)
106
+
107
+ for i, result in enumerate(results, 1):
108
+ level_symbol = {
109
+ "error": "❌",
110
+ "warning": "⚠️",
111
+ "info": "ℹ️"
112
+ }.get(result.level, "❓")
113
+
114
+ print(f"\n{i}. {level_symbol} [{result.level.upper()}]")
115
+ print(f" Message: {result.message}")
116
+
117
+ if hasattr(result, 'section') and result.section:
118
+ location = f"{result.section}"
119
+ if hasattr(result, 'key') and result.key:
120
+ location += f".{result.key}"
121
+ print(f" Location: {location}")
122
+
123
+ if hasattr(result, 'suggestion') and result.suggestion:
124
+ print(f" Suggestion: {result.suggestion}")
125
+
126
+ if verbose:
127
+ print(f" Full details: {result}")
128
+ else:
129
+ print("\n✅ No issues found in configuration!")
130
+
131
+ if fix_suggestions and results:
132
+ self._print_fix_suggestions(results)
133
+
134
+ def _print_fix_suggestions(self, results: list) -> None:
135
+ """Print suggestions for fixing configuration issues."""
136
+ print("\n🔧 FIX SUGGESTIONS:")
137
+ print("-" * 40)
138
+
139
+ # Group suggestions by type
140
+ suggestions = {
141
+ "missing_files": [],
142
+ "invalid_values": [],
143
+ "missing_sections": [],
144
+ "dependency_issues": [],
145
+ "other": []
146
+ }
147
+
148
+ for result in results:
149
+ if result.level == "error":
150
+ message = result.message.lower()
151
+ if "does not exist" in message or "not found" in message:
152
+ suggestions["missing_files"].append(result)
153
+ elif "missing" in message and "section" in message:
154
+ suggestions["missing_sections"].append(result)
155
+ elif "invalid" in message or "wrong type" in message:
156
+ suggestions["invalid_values"].append(result)
157
+ elif "dependency" in message or "requires" in message:
158
+ suggestions["dependency_issues"].append(result)
159
+ else:
160
+ suggestions["other"].append(result)
161
+
162
+ # Print suggestions by category
163
+ for category, issues in suggestions.items():
164
+ if issues:
165
+ print(f"\n📁 {category.replace('_', ' ').title()}:")
166
+ for issue in issues:
167
+ print(f" • {issue.message}")
168
+ if hasattr(issue, 'suggestion') and issue.suggestion:
169
+ print(f" → {issue.suggestion}")
170
+
171
+ print("\n💡 GENERAL RECOMMENDATIONS:")
172
+ print(" • Use the configuration generator: mcp-proxy-adapter generate --help")
173
+ print(" • Check the documentation: docs/EN/ALL_CONFIG_SETTINGS.md")
174
+ print(" • Validate certificates and file paths")
175
+ print(" • Ensure all required sections are present")
176
+
177
+
@@ -0,0 +1,8 @@
1
+ """
2
+ CLI Examples Module
3
+
4
+ This module contains example scripts demonstrating CLI usage.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ HTTP Basic Configuration Example
4
+
5
+ This example demonstrates how to generate and use a basic HTTP configuration.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import subprocess
12
+ import sys
13
+ import json
14
+ from pathlib import Path
15
+
16
+
17
+ def main():
18
+ """Generate and test HTTP basic configuration."""
19
+ print("🔧 HTTP Basic Configuration Example")
20
+ print("=" * 50)
21
+
22
+ # Generate HTTP configuration
23
+ print("1. Generating HTTP configuration...")
24
+ result = subprocess.run([
25
+ sys.executable, "-m", "mcp_proxy_adapter.cli.main",
26
+ "sets", "http",
27
+ "--port", "8080",
28
+ "--output-dir", "./examples_configs"
29
+ ], capture_output=True, text=True)
30
+
31
+ if result.returncode != 0:
32
+ print(f"❌ Error generating configuration: {result.stderr}")
33
+ return 1
34
+
35
+ print("✅ HTTP configuration generated")
36
+
37
+ # Find the generated config file
38
+ config_dir = Path("./examples_configs")
39
+ config_files = list(config_dir.glob("http*.json"))
40
+
41
+ if not config_files:
42
+ print("❌ No configuration files found")
43
+ return 1
44
+
45
+ config_file = config_files[0]
46
+ print(f"📁 Configuration file: {config_file}")
47
+
48
+ # Test the configuration
49
+ print("\n2. Testing configuration...")
50
+ result = subprocess.run([
51
+ sys.executable, "-m", "mcp_proxy_adapter.cli.main",
52
+ "testconfig",
53
+ "--config", str(config_file),
54
+ "--verbose"
55
+ ], capture_output=True, text=True)
56
+
57
+ if result.returncode != 0:
58
+ print(f"❌ Configuration validation failed: {result.stderr}")
59
+ return 1
60
+
61
+ print("✅ Configuration validation passed")
62
+
63
+ # Show configuration content
64
+ print("\n3. Configuration content:")
65
+ with open(config_file, 'r') as f:
66
+ config = json.load(f)
67
+
68
+ print(f" Protocol: {config['server']['protocol']}")
69
+ print(f" Host: {config['server']['host']}")
70
+ print(f" Port: {config['server']['port']}")
71
+ print(f" Security: {'Enabled' if config.get('security', {}).get('enabled') else 'Disabled'}")
72
+
73
+ print("\n🎉 HTTP basic configuration example completed!")
74
+ print(f"📁 Configuration saved to: {config_file}")
75
+ print("\n💡 To start the server:")
76
+ print(f" mcp-proxy-adapter server --config {config_file}")
77
+
78
+ return 0
79
+
80
+
81
+ if __name__ == "__main__":
82
+ sys.exit(main())
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ HTTPS Token Configuration Example
4
+
5
+ This example demonstrates how to generate and use an HTTPS configuration with token authentication.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import subprocess
12
+ import sys
13
+ import json
14
+ from pathlib import Path
15
+
16
+
17
+ def main():
18
+ """Generate and test HTTPS token configuration."""
19
+ print("🔧 HTTPS Token Configuration Example")
20
+ print("=" * 50)
21
+
22
+ # Generate HTTPS configuration with token authentication
23
+ print("1. Generating HTTPS configuration with token authentication...")
24
+ result = subprocess.run([
25
+ sys.executable, "-m", "mcp_proxy_adapter.cli.main",
26
+ "sets", "https",
27
+ "--token",
28
+ "--roles",
29
+ "--port", "8443",
30
+ "--output-dir", "./examples_configs"
31
+ ], capture_output=True, text=True)
32
+
33
+ if result.returncode != 0:
34
+ print(f"❌ Error generating configuration: {result.stderr}")
35
+ return 1
36
+
37
+ print("✅ HTTPS configuration with token authentication generated")
38
+
39
+ # Find the generated config file
40
+ config_dir = Path("./examples_configs")
41
+ config_files = list(config_dir.glob("https_token_roles*.json"))
42
+
43
+ if not config_files:
44
+ print("❌ No configuration files found")
45
+ return 1
46
+
47
+ config_file = config_files[0]
48
+ print(f"📁 Configuration file: {config_file}")
49
+
50
+ # Test the configuration
51
+ print("\n2. Testing configuration...")
52
+ result = subprocess.run([
53
+ sys.executable, "-m", "mcp_proxy_adapter.cli.main",
54
+ "testconfig",
55
+ "--config", str(config_file),
56
+ "--verbose"
57
+ ], capture_output=True, text=True)
58
+
59
+ if result.returncode != 0:
60
+ print(f"❌ Configuration validation failed: {result.stderr}")
61
+ return 1
62
+
63
+ print("✅ Configuration validation passed")
64
+
65
+ # Show configuration content
66
+ print("\n3. Configuration content:")
67
+ with open(config_file, 'r') as f:
68
+ config = json.load(f)
69
+
70
+ print(f" Protocol: {config['server']['protocol']}")
71
+ print(f" Host: {config['server']['host']}")
72
+ print(f" Port: {config['server']['port']}")
73
+ print(f" SSL: {'Enabled' if config.get('ssl', {}).get('enabled') else 'Disabled'}")
74
+ print(f" Security: {'Enabled' if config.get('security', {}).get('enabled') else 'Disabled'}")
75
+ print(f" Token Auth: {'Enabled' if config.get('security', {}).get('tokens') else 'Disabled'}")
76
+ print(f" Roles: {'Enabled' if config.get('roles', {}).get('enabled') else 'Disabled'}")
77
+
78
+ # Show available tokens
79
+ if config.get('security', {}).get('tokens'):
80
+ print("\n4. Available authentication tokens:")
81
+ for role, token in config['security']['tokens'].items():
82
+ print(f" {role}: {token}")
83
+
84
+ print("\n🎉 HTTPS token configuration example completed!")
85
+ print(f"📁 Configuration saved to: {config_file}")
86
+ print("\n💡 To start the server:")
87
+ print(f" mcp-proxy-adapter server --config {config_file}")
88
+ print("\n💡 To test with curl:")
89
+ print(f" curl -k https://localhost:8443/health")
90
+ print(f" curl -k -H 'X-API-Key: admin-secret-key' https://localhost:8443/api/jsonrpc -d '{{\"jsonrpc\":\"2.0\",\"method\":\"echo\",\"params\":{{\"message\":\"Hello\"}},\"id\":1}}'")
91
+
92
+ return 0
93
+
94
+
95
+ if __name__ == "__main__":
96
+ sys.exit(main())
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ mTLS Roles Configuration Example
4
+
5
+ This example demonstrates how to generate and use an mTLS configuration with role-based access control.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import subprocess
12
+ import sys
13
+ import json
14
+ from pathlib import Path
15
+
16
+
17
+ def main():
18
+ """Generate and test mTLS roles configuration."""
19
+ print("🔧 mTLS Roles Configuration Example")
20
+ print("=" * 50)
21
+
22
+ # Generate mTLS configuration with roles
23
+ print("1. Generating mTLS configuration with roles...")
24
+ result = subprocess.run([
25
+ sys.executable, "-m", "mcp_proxy_adapter.cli.main",
26
+ "sets", "mtls",
27
+ "--roles",
28
+ "--port", "8443",
29
+ "--output-dir", "./examples_configs"
30
+ ], capture_output=True, text=True)
31
+
32
+ if result.returncode != 0:
33
+ print(f"❌ Error generating configuration: {result.stderr}")
34
+ return 1
35
+
36
+ print("✅ mTLS configuration with roles generated")
37
+
38
+ # Find the generated config file
39
+ config_dir = Path("./examples_configs")
40
+ config_files = list(config_dir.glob("mtls_roles*.json"))
41
+
42
+ if not config_files:
43
+ print("❌ No configuration files found")
44
+ return 1
45
+
46
+ config_file = config_files[0]
47
+ print(f"📁 Configuration file: {config_file}")
48
+
49
+ # Test the configuration
50
+ print("\n2. Testing configuration...")
51
+ result = subprocess.run([
52
+ sys.executable, "-m", "mcp_proxy_adapter.cli.main",
53
+ "testconfig",
54
+ "--config", str(config_file),
55
+ "--verbose"
56
+ ], capture_output=True, text=True)
57
+
58
+ if result.returncode != 0:
59
+ print(f"❌ Configuration validation failed: {result.stderr}")
60
+ return 1
61
+
62
+ print("✅ Configuration validation passed")
63
+
64
+ # Show configuration content
65
+ print("\n3. Configuration content:")
66
+ with open(config_file, 'r') as f:
67
+ config = json.load(f)
68
+
69
+ print(f" Protocol: {config['server']['protocol']}")
70
+ print(f" Host: {config['server']['host']}")
71
+ print(f" Port: {config['server']['port']}")
72
+ print(f" SSL: {'Enabled' if config.get('ssl', {}).get('enabled') else 'Disabled'}")
73
+ print(f" Client Verification: {'Enabled' if config.get('transport', {}).get('verify_client') else 'Disabled'}")
74
+ print(f" Roles: {'Enabled' if config.get('roles', {}).get('enabled') else 'Disabled'}")
75
+
76
+ # Show SSL configuration
77
+ if config.get('ssl'):
78
+ ssl_config = config['ssl']
79
+ print(f"\n4. SSL Configuration:")
80
+ print(f" Certificate: {ssl_config.get('cert_file', 'Not set')}")
81
+ print(f" Private Key: {ssl_config.get('key_file', 'Not set')}")
82
+ print(f" CA Certificate: {ssl_config.get('ca_cert', 'Not set')}")
83
+
84
+ # Show roles configuration
85
+ if config.get('roles', {}).get('enabled'):
86
+ print(f"\n5. Roles Configuration:")
87
+ print(f" Config File: {config['roles'].get('config_file', 'Not set')}")
88
+ print(f" Auto Load: {config['roles'].get('auto_load', False)}")
89
+ print(f" Validation: {'Enabled' if config['roles'].get('validation_enabled') else 'Disabled'}")
90
+
91
+ print("\n🎉 mTLS roles configuration example completed!")
92
+ print(f"📁 Configuration saved to: {config_file}")
93
+ print("\n💡 To start the server:")
94
+ print(f" mcp-proxy-adapter server --config {config_file}")
95
+ print("\n💡 To test with curl (requires client certificates):")
96
+ print(f" curl -k --cert client.crt --key client.key https://localhost:8443/health")
97
+ print(f" curl -k --cert client.crt --key client.key https://localhost:8443/api/jsonrpc -d '{{\"jsonrpc\":\"2.0\",\"method\":\"echo\",\"params\":{{\"message\":\"Hello mTLS\"}},\"id\":1}}'")
98
+
99
+ return 0
100
+
101
+
102
+ if __name__ == "__main__":
103
+ sys.exit(main())
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ MCP Proxy Adapter CLI Application
4
+ Comprehensive command-line interface with multi-level help and configuration management
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ # Add project root to path
14
+ project_root = Path(__file__).parent.parent.parent
15
+ sys.path.insert(0, str(project_root))
16
+
17
+ from mcp_proxy_adapter.cli.parser import create_main_parser # noqa: E402
18
+
19
+
20
+ def main():
21
+ """Main CLI entry point"""
22
+ parser = create_main_parser()
23
+ args = parser.parse_args()
24
+
25
+ try:
26
+ if args.command == 'generate':
27
+ from mcp_proxy_adapter.cli.commands.generate import GenerateCommand
28
+ return GenerateCommand().execute(vars(args))
29
+ elif args.command == 'testconfig':
30
+ from mcp_proxy_adapter.cli.commands.testconfig import TestConfigCommand
31
+ return TestConfigCommand().execute(vars(args))
32
+ elif args.command == 'sets':
33
+ from mcp_proxy_adapter.cli.commands.sets import SetsCommand
34
+ return SetsCommand().execute(vars(args))
35
+ elif args.command == 'server':
36
+ from mcp_proxy_adapter.cli.commands.server import ServerCommand
37
+ return ServerCommand().execute(vars(args))
38
+ elif args.command == 'config':
39
+ if args.config_command == 'generate':
40
+ from mcp_proxy_adapter.cli.commands.config_generate import config_generate_command
41
+ return config_generate_command(args)
42
+ if args.config_command == 'validate':
43
+ from mcp_proxy_adapter.cli.commands.config_validate import config_validate_command
44
+ return config_validate_command(args)
45
+ print('Available: config generate|validate')
46
+ return 1
47
+ elif args.command == 'client':
48
+ from mcp_proxy_adapter.cli.commands.client import client_command
49
+ return client_command(args)
50
+ else:
51
+ parser.print_help()
52
+ return 1
53
+
54
+ except KeyboardInterrupt:
55
+ print("\n❌ Operation cancelled by user")
56
+ return 1
57
+ except Exception as e:
58
+ print(f"❌ Error: {e}")
59
+ return 1
60
+
61
+
62
+ if __name__ == "__main__":
63
+ sys.exit(main())