mcp-proxy-adapter 4.1.1__py3-none-any.whl → 6.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. mcp_proxy_adapter/__main__.py +32 -0
  2. mcp_proxy_adapter/api/app.py +290 -33
  3. mcp_proxy_adapter/api/handlers.py +32 -6
  4. mcp_proxy_adapter/api/middleware/__init__.py +38 -32
  5. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  6. mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
  7. mcp_proxy_adapter/api/middleware/factory.py +243 -0
  8. mcp_proxy_adapter/api/middleware/logging.py +32 -6
  9. mcp_proxy_adapter/api/middleware/protocol_middleware.py +201 -0
  10. mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
  11. mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
  12. mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
  13. mcp_proxy_adapter/commands/__init__.py +19 -4
  14. mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
  15. mcp_proxy_adapter/commands/base.py +66 -32
  16. mcp_proxy_adapter/commands/builtin_commands.py +95 -0
  17. mcp_proxy_adapter/commands/catalog_manager.py +838 -0
  18. mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
  19. mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
  20. mcp_proxy_adapter/commands/command_registry.py +711 -354
  21. mcp_proxy_adapter/commands/dependency_manager.py +245 -0
  22. mcp_proxy_adapter/commands/echo_command.py +81 -0
  23. mcp_proxy_adapter/commands/health_command.py +8 -1
  24. mcp_proxy_adapter/commands/help_command.py +21 -14
  25. mcp_proxy_adapter/commands/hooks.py +200 -167
  26. mcp_proxy_adapter/commands/key_management_command.py +506 -0
  27. mcp_proxy_adapter/commands/load_command.py +176 -0
  28. mcp_proxy_adapter/commands/plugins_command.py +235 -0
  29. mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
  30. mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
  31. mcp_proxy_adapter/commands/reload_command.py +48 -50
  32. mcp_proxy_adapter/commands/result.py +1 -0
  33. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  34. mcp_proxy_adapter/commands/roles_management_command.py +697 -0
  35. mcp_proxy_adapter/commands/security_command.py +488 -0
  36. mcp_proxy_adapter/commands/ssl_setup_command.py +366 -0
  37. mcp_proxy_adapter/commands/token_management_command.py +529 -0
  38. mcp_proxy_adapter/commands/transport_management_command.py +144 -0
  39. mcp_proxy_adapter/commands/unload_command.py +158 -0
  40. mcp_proxy_adapter/config.py +394 -14
  41. mcp_proxy_adapter/core/app_factory.py +410 -0
  42. mcp_proxy_adapter/core/app_runner.py +272 -0
  43. mcp_proxy_adapter/core/auth_validator.py +606 -0
  44. mcp_proxy_adapter/core/certificate_utils.py +1045 -0
  45. mcp_proxy_adapter/core/client.py +574 -0
  46. mcp_proxy_adapter/core/client_manager.py +284 -0
  47. mcp_proxy_adapter/core/client_security.py +384 -0
  48. mcp_proxy_adapter/core/config_converter.py +405 -0
  49. mcp_proxy_adapter/core/config_validator.py +218 -0
  50. mcp_proxy_adapter/core/logging.py +19 -3
  51. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  52. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  53. mcp_proxy_adapter/core/protocol_manager.py +385 -0
  54. mcp_proxy_adapter/core/proxy_client.py +602 -0
  55. mcp_proxy_adapter/core/proxy_registration.py +522 -0
  56. mcp_proxy_adapter/core/role_utils.py +426 -0
  57. mcp_proxy_adapter/core/security_adapter.py +370 -0
  58. mcp_proxy_adapter/core/security_factory.py +239 -0
  59. mcp_proxy_adapter/core/security_integration.py +286 -0
  60. mcp_proxy_adapter/core/server_adapter.py +282 -0
  61. mcp_proxy_adapter/core/server_engine.py +270 -0
  62. mcp_proxy_adapter/core/settings.py +1 -0
  63. mcp_proxy_adapter/core/ssl_utils.py +234 -0
  64. mcp_proxy_adapter/core/transport_manager.py +292 -0
  65. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  66. mcp_proxy_adapter/custom_openapi.py +22 -11
  67. mcp_proxy_adapter/examples/__init__.py +13 -4
  68. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  69. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  70. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  71. mcp_proxy_adapter/examples/basic_framework/main.py +44 -0
  72. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  73. mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
  74. mcp_proxy_adapter/examples/debug_request_state.py +112 -0
  75. mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
  76. mcp_proxy_adapter/examples/demo_client.py +275 -0
  77. mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
  78. mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
  79. mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
  80. mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
  81. mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
  82. mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
  83. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
  84. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  85. mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
  86. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
  87. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  88. mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
  89. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
  90. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  91. mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
  92. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
  93. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  94. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
  95. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
  96. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  97. mcp_proxy_adapter/examples/full_application/main.py +173 -0
  98. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
  99. mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
  100. mcp_proxy_adapter/examples/generate_certificates.py +177 -0
  101. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
  102. mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
  103. mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
  104. mcp_proxy_adapter/examples/run_example.py +59 -0
  105. mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
  106. mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
  107. mcp_proxy_adapter/examples/run_security_tests.py +544 -0
  108. mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
  109. mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
  110. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
  111. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
  112. mcp_proxy_adapter/examples/security_test_client.py +782 -0
  113. mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
  114. mcp_proxy_adapter/examples/test_config.py +148 -0
  115. mcp_proxy_adapter/examples/test_config_generator.py +86 -0
  116. mcp_proxy_adapter/examples/test_examples.py +281 -0
  117. mcp_proxy_adapter/examples/universal_client.py +620 -0
  118. mcp_proxy_adapter/main.py +93 -0
  119. mcp_proxy_adapter/utils/config_generator.py +1008 -0
  120. mcp_proxy_adapter/version.py +5 -2
  121. mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
  122. mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
  123. mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
  124. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
  125. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  126. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  127. mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
  128. mcp_proxy_adapter/examples/README.md +0 -124
  129. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  130. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  131. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  132. mcp_proxy_adapter/examples/basic_server/config.json +0 -35
  133. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  134. mcp_proxy_adapter/examples/basic_server/server.py +0 -103
  135. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  136. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  137. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -250
  138. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  139. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  140. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  141. mcp_proxy_adapter/examples/custom_commands/config.json +0 -35
  142. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  143. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  144. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  145. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  146. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  147. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  148. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  149. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  150. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  151. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  152. mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
  153. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  154. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  155. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  156. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  157. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  158. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  159. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  160. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  161. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  162. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  163. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  164. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  165. mcp_proxy_adapter/tests/__init__.py +0 -0
  166. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  167. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  168. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  169. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  170. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  171. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  172. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  173. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  174. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  175. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  176. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  177. mcp_proxy_adapter/tests/conftest.py +0 -131
  178. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  179. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  180. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  181. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  182. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  183. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  184. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  185. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  186. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  187. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  188. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  189. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  190. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  191. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  192. mcp_proxy_adapter/tests/test_config.py +0 -127
  193. mcp_proxy_adapter/tests/test_utils.py +0 -65
  194. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  195. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  196. mcp_proxy_adapter/tests/unit/test_config.py +0 -217
  197. mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
  198. mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
  199. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
  200. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,328 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Author: Vasiliy Zdanovskiy
4
+ email: vasilyvz@gmail.com
5
+ Script for setting up test environment for MCP Proxy Adapter.
6
+ Prepares the test environment with all necessary files and directories.
7
+ Uses mcp_security_framework for certificate generation.
8
+
9
+ This script accepts an output directory and copies required example files
10
+ and helper scripts into that directory, creating a ready-to-use workspace.
11
+ By default, the current working directory is used, so end-users can run
12
+ it in their project root after installing this framework in a virtual
13
+ environment.
14
+ """
15
+ import shutil
16
+ import sys
17
+ import argparse
18
+ from pathlib import Path
19
+ # Import mcp_security_framework
20
+ try:
21
+ from mcp_security_framework.core.cert_manager import CertificateManager
22
+ from mcp_security_framework.schemas.config import (
23
+ CertificateConfig,
24
+ CAConfig,
25
+ ServerCertConfig,
26
+ ClientCertConfig,
27
+ )
28
+ SECURITY_FRAMEWORK_AVAILABLE = True
29
+ except ImportError:
30
+ SECURITY_FRAMEWORK_AVAILABLE = False
31
+ print("Warning: mcp_security_framework not available")
32
+
33
+
34
+ def _get_package_paths() -> tuple[Path, Path]:
35
+ """
36
+ Resolve source paths for examples and utils relative to this file
37
+ to avoid importing the package during setup.
38
+ """
39
+ pkg_root = Path(__file__).resolve().parents[1]
40
+ return pkg_root / "examples", pkg_root / "utils"
41
+
42
+
43
+ def setup_test_environment(output_dir: Path) -> None:
44
+ """
45
+ Setup test environment under output_dir with required files
46
+ and directories.
47
+
48
+ All created directories and copied files are rooted at output_dir
49
+ so users can run scripts relative to that directory.
50
+ """
51
+ print("🔧 Setting up test environment...")
52
+ output_dir = output_dir.resolve()
53
+ output_dir.mkdir(parents=True, exist_ok=True)
54
+ # Create test environment directory structure
55
+ directories = [
56
+ "examples/basic_framework",
57
+ "examples/full_application",
58
+ "scripts",
59
+ "configs",
60
+ "certs",
61
+ "keys",
62
+ "tokens",
63
+ "logs"
64
+ ]
65
+ for directory in directories:
66
+ target_dir = output_dir / directory
67
+ target_dir.mkdir(parents=True, exist_ok=True)
68
+ print(f"✅ Created directory: {target_dir}")
69
+ # Resolve package paths
70
+ examples_src_root, utils_src_root = _get_package_paths()
71
+ # Copy example files
72
+ basic_framework_src = examples_src_root / "basic_framework"
73
+ if basic_framework_src.exists():
74
+ shutil.copytree(
75
+ basic_framework_src,
76
+ output_dir / "examples/basic_framework",
77
+ dirs_exist_ok=True,
78
+ )
79
+ print("✅ Copied basic_framework examples")
80
+ full_application_src = examples_src_root / "full_application"
81
+ if full_application_src.exists():
82
+ shutil.copytree(
83
+ full_application_src,
84
+ output_dir / "examples/full_application",
85
+ dirs_exist_ok=True,
86
+ )
87
+ print("✅ Copied full_application examples")
88
+ # Copy utility scripts
89
+ config_generator_src = utils_src_root / "config_generator.py"
90
+ if config_generator_src.exists():
91
+ shutil.copy2(config_generator_src, output_dir / "scripts/")
92
+ print("✅ Copied config_generator.py")
93
+ # Copy certificate generation scripts
94
+ create_certs_src = examples_src_root / "create_certificates_simple.py"
95
+ if create_certs_src.exists():
96
+ shutil.copy2(create_certs_src, output_dir / "scripts/")
97
+ print("✅ Copied create_certificates_simple.py")
98
+ cert_tokens_src = examples_src_root / "generate_certificates_and_tokens.py"
99
+ if cert_tokens_src.exists():
100
+ shutil.copy2(cert_tokens_src, output_dir / "scripts/")
101
+ print("✅ Copied generate_certificates_and_tokens.py")
102
+
103
+ # Copy roles.json to the root directory for compatibility
104
+ roles_src = examples_src_root / "roles.json"
105
+ if roles_src.exists():
106
+ shutil.copy2(roles_src, output_dir)
107
+ print("✅ Copied roles.json to root directory")
108
+
109
+ # Also copy from configs directory if it exists
110
+ roles_configs_src = output_dir / "configs" / "roles.json"
111
+ if roles_configs_src.exists():
112
+ shutil.copy2(roles_configs_src, output_dir / "roles.json")
113
+ print("✅ Updated roles.json from configs directory")
114
+ print(
115
+ "🎉 Test environment setup completed successfully at: {}".format(
116
+ output_dir
117
+ )
118
+ )
119
+
120
+
121
+ def generate_certificates_with_framework(output_dir: Path) -> bool:
122
+ """
123
+ Generate certificates using mcp_security_framework.
124
+ """
125
+ if not SECURITY_FRAMEWORK_AVAILABLE:
126
+ print(
127
+ "❌ mcp_security_framework not available for certificate "
128
+ "generation"
129
+ )
130
+ return False
131
+ try:
132
+ print(
133
+ "🔐 Generating certificates using mcp_security_framework..."
134
+ )
135
+ # Configure certificate manager
136
+ cert_config = CertificateConfig(
137
+ cert_storage_path=str((output_dir / "certs").resolve()),
138
+ key_storage_path=str((output_dir / "keys").resolve()),
139
+ default_validity_days=365,
140
+ key_size=2048,
141
+ hash_algorithm="sha256",
142
+ )
143
+ cert_manager = CertificateManager(cert_config)
144
+ # Generate CA certificate
145
+ ca_config = CAConfig(
146
+ common_name="MCP Proxy Adapter Test CA",
147
+ organization="Test Organization",
148
+ organizational_unit="Certificate Authority",
149
+ country="US",
150
+ state="Test State",
151
+ locality="Test City",
152
+ validity_years=10, # Use validity_years instead of validity_days
153
+ key_size=2048,
154
+ hash_algorithm="sha256",
155
+ )
156
+ cert_pair = cert_manager.create_root_ca(ca_config)
157
+ if not cert_pair or not cert_pair.certificate_path:
158
+ print(
159
+ "❌ Failed to create CA certificate: Invalid certificate pair"
160
+ )
161
+ return False
162
+ print("✅ CA certificate created successfully")
163
+ # Find CA key file
164
+ ca_key_path = cert_pair.private_key_path
165
+ # Generate server certificate
166
+ server_config = ServerCertConfig(
167
+ common_name="localhost",
168
+ organization="Test Organization",
169
+ organizational_unit="Server",
170
+ country="US",
171
+ state="Test State",
172
+ locality="Test City",
173
+ validity_days=365,
174
+ key_size=2048,
175
+ hash_algorithm="sha256",
176
+ subject_alt_names=[
177
+ "localhost",
178
+ "127.0.0.1",
179
+ ],
180
+ ca_cert_path=cert_pair.certificate_path,
181
+ ca_key_path=ca_key_path,
182
+ )
183
+ cert_pair = cert_manager.create_server_certificate(server_config)
184
+ if not cert_pair or not cert_pair.certificate_path:
185
+ print(
186
+ "❌ Failed to create server certificate: Invalid certificate "
187
+ "pair"
188
+ )
189
+ return False
190
+ print("✅ Server certificate created successfully")
191
+ # Generate client certificates
192
+ client_configs = [
193
+ (
194
+ "admin",
195
+ ["admin"],
196
+ [
197
+ "read",
198
+ "write",
199
+ "execute",
200
+ "delete",
201
+ "admin",
202
+ "register",
203
+ "unregister",
204
+ "heartbeat",
205
+ "discover",
206
+ ],
207
+ ),
208
+ (
209
+ "user",
210
+ ["user"],
211
+ [
212
+ "read",
213
+ "execute",
214
+ "register",
215
+ "unregister",
216
+ "heartbeat",
217
+ "discover",
218
+ ],
219
+ ),
220
+ ("readonly", ["readonly"], ["read", "discover"]),
221
+ ("guest", ["guest"], ["read", "discover"]),
222
+ (
223
+ "proxy",
224
+ ["proxy"],
225
+ ["register", "unregister", "heartbeat", "discover"],
226
+ ),
227
+ ]
228
+ for client_name, roles, permissions in client_configs:
229
+ client_config = ClientCertConfig(
230
+ common_name=f"{client_name}-client",
231
+ organization="Test Organization",
232
+ organizational_unit="Client",
233
+ country="US",
234
+ state="Test State",
235
+ locality="Test City",
236
+ validity_days=730,
237
+ key_size=2048,
238
+ hash_algorithm="sha256",
239
+ roles=roles,
240
+ permissions=permissions,
241
+ ca_cert_path=cert_pair.certificate_path,
242
+ ca_key_path=ca_key_path
243
+ )
244
+ cert_pair = cert_manager.create_client_certificate(client_config)
245
+ if not cert_pair or not cert_pair.certificate_path:
246
+ print(
247
+ (
248
+ "❌ Failed to create client certificate {}: "
249
+ "Invalid certificate pair"
250
+ ).format(client_name)
251
+ )
252
+ return False
253
+ print(
254
+ "✅ Client certificate {} created successfully".format(
255
+ client_name
256
+ )
257
+ )
258
+ print(
259
+ "🎉 All certificates generated successfully using "
260
+ "mcp_security_framework!"
261
+ )
262
+ return True
263
+ except Exception as e:
264
+ print("❌ Error generating certificates with framework: {}".format(e))
265
+ print("\n🔧 TROUBLESHOOTING:")
266
+ print("1. Check if mcp_security_framework is installed:")
267
+ print(" pip install mcp_security_framework")
268
+ print("\n2. Verify write permissions in output directory")
269
+ print("\n3. Check if certs/ and keys/ directories exist")
270
+ return False
271
+
272
+
273
+ def main() -> int:
274
+ """Main function for command line execution."""
275
+ parser = argparse.ArgumentParser(
276
+ description="Setup test environment for MCP Proxy Adapter"
277
+ )
278
+ parser.add_argument(
279
+ "--output-dir",
280
+ "-o",
281
+ type=str,
282
+ default=".",
283
+ help=(
284
+ "Target directory to create the test environment "
285
+ "(default: current directory)"
286
+ ),
287
+ )
288
+ args = parser.parse_args()
289
+ try:
290
+ target_root = Path(args.output_dir)
291
+ setup_test_environment(target_root)
292
+ # Generate certificates if framework is available
293
+ if SECURITY_FRAMEWORK_AVAILABLE:
294
+ generate_certificates_with_framework(target_root)
295
+ else:
296
+ print(
297
+ "⚠️ Skipping certificate generation (mcp_security_framework "
298
+ "not available)"
299
+ )
300
+ except Exception as e:
301
+ print(
302
+ "❌ Error setting up test environment: {}".format(e),
303
+ file=sys.stderr,
304
+ )
305
+ print("\n🔧 TROUBLESHOOTING:")
306
+ print("1. Check if output directory is writable")
307
+ print("2. Verify mcp_security_framework installation")
308
+ print("3. Check available disk space")
309
+ return 1
310
+
311
+ print("\n" + "=" * 60)
312
+ print("✅ TEST ENVIRONMENT SETUP COMPLETED SUCCESSFULLY")
313
+ print("=" * 60)
314
+ print("\n📋 NEXT STEPS:")
315
+ print("1. Generate test configurations:")
316
+ print(" python -m mcp_proxy_adapter.examples.generate_test_configs --output-dir configs")
317
+ print("\n2. Generate additional certificates (if needed):")
318
+ print(" python -m mcp_proxy_adapter.examples.generate_certificates")
319
+ print("\n3. Run security tests:")
320
+ print(" python -m mcp_proxy_adapter.examples.run_security_tests")
321
+ print("\n4. Start basic framework example:")
322
+ print(" python -m mcp_proxy_adapter.examples.basic_framework.main --config configs/https_simple.json")
323
+ print("=" * 60)
324
+ return 0
325
+
326
+
327
+ if __name__ == "__main__":
328
+ exit(main())
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Author: Vasiliy Zdanovskiy
4
+ email: vasilyvz@gmail.com
5
+ Script for testing MCP Proxy Adapter configurations.
6
+ Tests a specific configuration by creating an application and validating it.
7
+ Uses mcp_security_framework for security validation.
8
+ """
9
+ import json
10
+ import os
11
+ import sys
12
+ import argparse
13
+ import time
14
+ import subprocess
15
+ from pathlib import Path
16
+ from typing import Dict, Any, Optional
17
+ # Import mcp_security_framework
18
+ try:
19
+ from mcp_security_framework import SecurityManager
20
+ from mcp_security_framework.schemas.config import SecurityConfig
21
+ SECURITY_FRAMEWORK_AVAILABLE = True
22
+ except ImportError:
23
+ SECURITY_FRAMEWORK_AVAILABLE = False
24
+ print("Warning: mcp_security_framework not available")
25
+ # Add parent directory to path to import mcp_proxy_adapter
26
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../.."))
27
+ def validate_security_config(config: Dict[str, Any]) -> bool:
28
+ """
29
+ Validate security configuration using mcp_security_framework.
30
+ Args:
31
+ config: Configuration dictionary
32
+ Returns:
33
+ True if validation passed, False otherwise
34
+ """
35
+ if not SECURITY_FRAMEWORK_AVAILABLE:
36
+ print("⚠️ Skipping security validation (mcp_security_framework not available)")
37
+ return True
38
+ try:
39
+ security_section = config.get("security", {})
40
+ if not security_section.get("enabled", False):
41
+ print("🔓 Security framework disabled in configuration")
42
+ return True
43
+ print("🔒 Validating security configuration with mcp_security_framework...")
44
+ # Create SecurityConfig from configuration
45
+ security_config = SecurityConfig(
46
+ auth=security_section.get("auth", {}),
47
+ ssl=security_section.get("ssl", {}),
48
+ permissions=security_section.get("permissions", {}),
49
+ rate_limit=security_section.get("rate_limit", {})
50
+ )
51
+ # Create SecurityManager for validation
52
+ security_manager = SecurityManager(security_config)
53
+ # Validate configuration
54
+ validation_result = security_manager.validate_configuration()
55
+ if validation_result.is_valid:
56
+ print("✅ Security configuration validation passed")
57
+ return True
58
+ else:
59
+ print("❌ Security configuration validation failed:")
60
+ for error in validation_result.errors:
61
+ print(f" - {error}")
62
+ return False
63
+ except Exception as e:
64
+ print(f"❌ Error validating security configuration: {e}")
65
+ return False
66
+ def test_configuration(config_path: str, timeout: int = 30) -> bool:
67
+ """
68
+ Test a configuration by creating an application and validating it.
69
+ Args:
70
+ config_path: Path to configuration file
71
+ timeout: Timeout in seconds for server startup
72
+ Returns:
73
+ True if test passed, False otherwise
74
+ """
75
+ print(f"🧪 Testing configuration: {config_path}")
76
+ print("=" * 60)
77
+ try:
78
+ # Load configuration
79
+ with open(config_path, 'r') as f:
80
+ config = json.load(f)
81
+ # Import required modules
82
+ from mcp_proxy_adapter.core.app_factory import create_application
83
+ from mcp_proxy_adapter.core.app_runner import ApplicationRunner
84
+ # Create application
85
+ print("🔧 Creating application...")
86
+ app = create_application(config)
87
+ print("✅ Application created successfully")
88
+ # Create runner and validate configuration
89
+ print("🔍 Validating configuration...")
90
+ runner = ApplicationRunner(app, config)
91
+ errors = runner.validate_configuration()
92
+ if errors:
93
+ print("❌ Configuration validation failed:")
94
+ for error in errors:
95
+ print(f" - {error}")
96
+ return False
97
+ print("✅ Configuration validation passed")
98
+ # Validate security configuration
99
+ if not validate_security_config(config):
100
+ return False
101
+ # Test server startup (without actually starting)
102
+ print("🚀 Testing server startup...")
103
+ server_config = config.get("server", {})
104
+ host = server_config.get("host", "127.0.0.1")
105
+ port = server_config.get("port", 8000)
106
+ print(f"✅ Server configuration: {host}:{port}")
107
+ # Test SSL configuration if enabled
108
+ ssl_config = config.get("ssl", {})
109
+ if ssl_config.get("enabled", False):
110
+ print("🔐 SSL configuration:")
111
+ print(f" - Certificate: {ssl_config.get('cert_file', 'N/A')}")
112
+ print(f" - Key: {ssl_config.get('key_file', 'N/A')}")
113
+ print(f" - Client verification: {ssl_config.get('verify_client', False)}")
114
+ # Test security configuration if enabled
115
+ security_config = config.get("security", {})
116
+ if security_config.get("enabled", False):
117
+ print("🔒 Security configuration:")
118
+ auth_config = security_config.get("auth", {})
119
+ if auth_config.get("enabled", False):
120
+ methods = auth_config.get("methods", [])
121
+ print(f" - Authentication methods: {methods}")
122
+ permissions_config = security_config.get("permissions", {})
123
+ if permissions_config.get("enabled", False):
124
+ print(f" - Roles file: {permissions_config.get('roles_file', 'N/A')}")
125
+ # Test protocol configuration
126
+ protocols_config = config.get("protocols", {})
127
+ if protocols_config.get("enabled", False):
128
+ allowed_protocols = protocols_config.get("allowed_protocols", [])
129
+ print(f"🌐 Allowed protocols: {allowed_protocols}")
130
+ print("=" * 60)
131
+ print("✅ Configuration test completed successfully!")
132
+ return True
133
+ except Exception as e:
134
+ print(f"❌ Configuration test failed: {e}")
135
+ return False
136
+ def main():
137
+ """Main function for command line execution."""
138
+ parser = argparse.ArgumentParser(description="Test MCP Proxy Adapter configuration")
139
+ parser.add_argument("--config", "-c", required=True, help="Path to configuration file")
140
+ parser.add_argument("--timeout", "-t", type=int, default=30, help="Timeout in seconds")
141
+ args = parser.parse_args()
142
+ if not os.path.exists(args.config):
143
+ print(f"❌ Configuration file not found: {args.config}")
144
+ return 1
145
+ success = test_configuration(args.config, args.timeout)
146
+ return 0 if success else 1
147
+ if __name__ == "__main__":
148
+ exit(main())
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script for configuration generator utility.
4
+ This script tests the configuration generator to ensure it properly generates
5
+ configurations with the new protocols section and fixes for ProtocolMiddleware issues.
6
+ """
7
+ import sys
8
+ import json
9
+ from pathlib import Path
10
+ # Add the project root to the path
11
+ project_root = Path(__file__).parent.parent.parent
12
+ sys.path.insert(0, str(project_root))
13
+ from mcp_proxy_adapter.utils.config_generator import ConfigGenerator
14
+ def test_config_generator():
15
+ """Test the configuration generator with different types."""
16
+ generator = ConfigGenerator()
17
+ # Test configuration types
18
+ config_types = [
19
+ "basic_http",
20
+ "http_token",
21
+ "https",
22
+ "https_token",
23
+ "https_no_protocol_middleware",
24
+ "mtls",
25
+ "mtls_no_protocol_middleware"
26
+ ]
27
+ print("Testing Configuration Generator")
28
+ print("=" * 50)
29
+ for config_type in config_types:
30
+ print(f"\nTesting {config_type} configuration:")
31
+ print("-" * 30)
32
+ try:
33
+ # Generate configuration
34
+ config = generator._get_config_by_type(config_type)
35
+ # Check if protocols section exists
36
+ if "protocols" in config:
37
+ protocols = config["protocols"]
38
+ print(f"✅ Protocols section found:")
39
+ print(f" - enabled: {protocols.get('enabled', 'NOT SET')}")
40
+ print(f" - allowed_protocols: {protocols.get('allowed_protocols', 'NOT SET')}")
41
+ print(f" - default_protocol: {protocols.get('default_protocol', 'NOT SET')}")
42
+ else:
43
+ print("❌ Protocols section missing!")
44
+ # Check SSL configuration
45
+ ssl_enabled = config.get("ssl", {}).get("enabled", False)
46
+ security_ssl_enabled = config.get("security", {}).get("ssl", {}).get("enabled", False)
47
+ print(f" - legacy ssl.enabled: {ssl_enabled}")
48
+ print(f" - security.ssl.enabled: {security_ssl_enabled}")
49
+ # Check if configuration is valid for its type
50
+ if config_type == "https_no_protocol_middleware" or config_type == "mtls_no_protocol_middleware":
51
+ if protocols.get("enabled") == False:
52
+ print("✅ ProtocolMiddleware correctly disabled")
53
+ else:
54
+ print("❌ ProtocolMiddleware should be disabled but is enabled")
55
+ else:
56
+ if protocols.get("enabled") == True:
57
+ print("✅ ProtocolMiddleware correctly enabled")
58
+ else:
59
+ print("❌ ProtocolMiddleware should be enabled but is disabled")
60
+ # Save configuration to file for inspection
61
+ output_file = f"test_config_{config_type}.json"
62
+ with open(output_file, 'w') as f:
63
+ json.dump(config, f, indent=2)
64
+ print(f" - Configuration saved to {output_file}")
65
+ except Exception as e:
66
+ print(f"❌ Error generating {config_type} configuration: {e}")
67
+ print("\n" + "=" * 50)
68
+ print("Configuration generator test completed!")
69
+ def test_config_with_comments():
70
+ """Test configuration generation with comments."""
71
+ generator = ConfigGenerator()
72
+ print("\nTesting configuration with comments:")
73
+ print("-" * 40)
74
+ try:
75
+ # Generate HTTPS configuration with comments
76
+ commented_config = generator.generate_config_with_comments("https")
77
+ print("✅ HTTPS configuration with comments generated successfully")
78
+ # Save to file
79
+ with open("test_https_with_comments.json", 'w') as f:
80
+ f.write(commented_config)
81
+ print(" - Configuration saved to test_https_with_comments.json")
82
+ except Exception as e:
83
+ print(f"❌ Error generating configuration with comments: {e}")
84
+ if __name__ == "__main__":
85
+ test_config_generator()
86
+ test_config_with_comments()