mcp-proxy-adapter 6.4.10__py3-none-any.whl → 6.4.12__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.
@@ -43,8 +43,9 @@ def main():
43
43
  title="Basic Framework Example",
44
44
  description="Basic MCP Proxy Adapter with minimal configuration",
45
45
  version="1.0.0",
46
- host=config_overrides.get("host", "0.0.0.0"),
47
- log_level="debug" if config_overrides.get("debug", False) else "info",
46
+ host=config_overrides.get("host"),
47
+ port=config_overrides.get("port"),
48
+ debug=config_overrides.get("debug", False),
48
49
  ))
49
50
 
50
51
 
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test Configuration Generator
4
+ Creates test configurations by copying the comprehensive config and enabling/disabling specific options.
5
+ Author: Vasiliy Zdanovskiy
6
+ email: vasilyvz@gmail.com
7
+ """
8
+ import json
9
+ import shutil
10
+ from pathlib import Path
11
+ from typing import Dict, Any, Optional
12
+
13
+
14
+ class TestConfigGenerator:
15
+ """Generator for test configurations based on comprehensive config."""
16
+
17
+ def __init__(self, comprehensive_config_path: str, output_dir: str = "configs"):
18
+ """
19
+ Initialize the generator.
20
+
21
+ Args:
22
+ comprehensive_config_path: Path to the comprehensive configuration file
23
+ output_dir: Directory to output test configurations
24
+ """
25
+ self.comprehensive_config_path = Path(comprehensive_config_path)
26
+ self.output_dir = Path(output_dir)
27
+ self.output_dir.mkdir(exist_ok=True)
28
+
29
+ # Load the comprehensive config
30
+ with open(self.comprehensive_config_path, 'r', encoding='utf-8') as f:
31
+ self.base_config = json.load(f)
32
+
33
+ def create_config(self, name: str, modifications: Dict[str, Any]) -> Path:
34
+ """
35
+ Create a test configuration with specific modifications.
36
+
37
+ Args:
38
+ name: Name of the configuration (without .json extension)
39
+ modifications: Dictionary of modifications to apply
40
+
41
+ Returns:
42
+ Path to the created configuration file
43
+ """
44
+ # Deep copy the base config
45
+ config = json.loads(json.dumps(self.base_config))
46
+
47
+ # Apply modifications
48
+ for key, value in modifications.items():
49
+ self._set_nested_value(config, key, value)
50
+
51
+ # Save the configuration
52
+ output_path = self.output_dir / f"{name}.json"
53
+ with open(output_path, 'w', encoding='utf-8') as f:
54
+ json.dump(config, f, indent=2, ensure_ascii=False)
55
+
56
+ print(f"✅ Created test config: {output_path}")
57
+ return output_path
58
+
59
+ def _set_nested_value(self, config: Dict, key: str, value: Any):
60
+ """Set a nested value in the configuration using dot notation."""
61
+ keys = key.split('.')
62
+ current = config
63
+
64
+ for k in keys[:-1]:
65
+ if k not in current:
66
+ current[k] = {}
67
+ current = current[k]
68
+
69
+ current[keys[-1]] = value
70
+
71
+ def create_all_test_configs(self):
72
+ """Create all standard test configurations."""
73
+ print("🔧 Creating test configurations from comprehensive config...")
74
+
75
+ # 1. HTTP Simple
76
+ self.create_config("http_simple", {
77
+ "server.port": 8001,
78
+ "ssl.enabled": False,
79
+ "security.enabled": False,
80
+ "proxy_registration.enabled": False,
81
+ "protocols.allowed_protocols": ["http"]
82
+ })
83
+
84
+ # 2. HTTP with Auth
85
+ self.create_config("http_auth", {
86
+ "server.port": 8002,
87
+ "ssl.enabled": False,
88
+ "security.enabled": True,
89
+ "security.auth.enabled": True,
90
+ "security.auth.methods": ["api_key"],
91
+ "security.auth.api_keys": {
92
+ "admin": "admin-secret-key",
93
+ "user": "user-secret-key"
94
+ },
95
+ "proxy_registration.enabled": False,
96
+ "protocols.allowed_protocols": ["http"]
97
+ })
98
+
99
+ # 3. HTTPS Simple
100
+ self.create_config("https_simple", {
101
+ "server.port": 8003,
102
+ "ssl.enabled": True,
103
+ "ssl.cert_file": "certs/localhost_server.crt",
104
+ "ssl.key_file": "keys/localhost_server.key",
105
+ "security.enabled": False,
106
+ "proxy_registration.enabled": False,
107
+ "protocols.allowed_protocols": ["https"]
108
+ })
109
+
110
+ # 4. HTTPS with Auth
111
+ self.create_config("https_auth", {
112
+ "server.port": 8004,
113
+ "ssl.enabled": True,
114
+ "ssl.cert_file": "certs/localhost_server.crt",
115
+ "ssl.key_file": "keys/localhost_server.key",
116
+ "security.enabled": True,
117
+ "security.auth.enabled": True,
118
+ "security.auth.methods": ["api_key"],
119
+ "security.auth.api_keys": {
120
+ "admin": "admin-secret-key",
121
+ "user": "user-secret-key"
122
+ },
123
+ "proxy_registration.enabled": False,
124
+ "protocols.allowed_protocols": ["https"]
125
+ })
126
+
127
+ # 5. mTLS Simple
128
+ self.create_config("mtls_simple", {
129
+ "server.port": 8005,
130
+ "ssl.enabled": True,
131
+ "ssl.cert_file": "certs/localhost_server.crt",
132
+ "ssl.key_file": "keys/localhost_server.key",
133
+ "ssl.ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
134
+ "ssl.verify_client": True,
135
+ "security.enabled": True,
136
+ "security.auth.enabled": True,
137
+ "security.auth.methods": ["certificate"],
138
+ "proxy_registration.enabled": False,
139
+ "protocols.allowed_protocols": ["https", "mtls"]
140
+ })
141
+
142
+ # 6. mTLS with Roles
143
+ self.create_config("mtls_with_roles", {
144
+ "server.port": 8006,
145
+ "ssl.enabled": True,
146
+ "ssl.cert_file": "certs/localhost_server.crt",
147
+ "ssl.key_file": "keys/localhost_server.key",
148
+ "ssl.ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
149
+ "ssl.verify_client": True,
150
+ "security.enabled": True,
151
+ "security.auth.enabled": True,
152
+ "security.auth.methods": ["certificate"],
153
+ "security.permissions.enabled": True,
154
+ "security.permissions.roles_file": "configs/roles.json",
155
+ "proxy_registration.enabled": False,
156
+ "protocols.allowed_protocols": ["https", "mtls"]
157
+ })
158
+
159
+ # 6a. mTLS without Roles (for security tests)
160
+ self.create_config("mtls_no_roles", {
161
+ "server.port": 8009,
162
+ "ssl.enabled": True,
163
+ "ssl.cert_file": "certs/localhost_server.crt",
164
+ "ssl.key_file": "keys/localhost_server.key",
165
+ "ssl.ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
166
+ "ssl.verify_client": True,
167
+ "security.enabled": True,
168
+ "security.auth.enabled": True,
169
+ "security.auth.methods": ["certificate"],
170
+ "security.permissions.enabled": False,
171
+ "proxy_registration.enabled": False,
172
+ "protocols.allowed_protocols": ["https", "mtls"]
173
+ })
174
+
175
+ # 7. mTLS with Proxy Registration
176
+ self.create_config("mtls_with_proxy", {
177
+ "server.port": 8007,
178
+ "ssl.enabled": True,
179
+ "ssl.cert_file": "certs/localhost_server.crt",
180
+ "ssl.key_file": "keys/localhost_server.key",
181
+ "ssl.ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
182
+ "ssl.verify_client": True,
183
+ "security.enabled": True,
184
+ "security.auth.enabled": True,
185
+ "security.auth.methods": ["certificate"],
186
+ "proxy_registration.enabled": True,
187
+ "proxy_registration.proxy_url": "http://127.0.0.1:3006",
188
+ "proxy_registration.server_id": "mcp_test_server",
189
+ "proxy_registration.server_name": "MCP Test Server",
190
+ "protocols.allowed_protocols": ["https", "mtls"]
191
+ })
192
+
193
+ # 8. HTTP with Token Auth (for security tests)
194
+ self.create_config("http_token", {
195
+ "server.port": 8010,
196
+ "ssl.enabled": False,
197
+ "security.enabled": True,
198
+ "security.auth.enabled": True,
199
+ "security.auth.methods": ["api_key"],
200
+ "security.auth.api_keys": {
201
+ "admin": "admin-secret-key",
202
+ "user": "user-secret-key"
203
+ },
204
+ "proxy_registration.enabled": False,
205
+ "protocols.allowed_protocols": ["http"]
206
+ })
207
+
208
+ # 9. HTTPS with Token Auth (for security tests)
209
+ self.create_config("https_token", {
210
+ "server.port": 8011,
211
+ "ssl.enabled": True,
212
+ "ssl.cert_file": "certs/localhost_server.crt",
213
+ "ssl.key_file": "keys/localhost_server.key",
214
+ "security.enabled": True,
215
+ "security.auth.enabled": True,
216
+ "security.auth.methods": ["api_key"],
217
+ "security.auth.api_keys": {
218
+ "admin": "admin-secret-key",
219
+ "user": "user-secret-key"
220
+ },
221
+ "proxy_registration.enabled": False,
222
+ "protocols.allowed_protocols": ["https"]
223
+ })
224
+
225
+ # 10. Full Featured (everything enabled)
226
+ self.create_config("full_featured", {
227
+ "server.port": 8008,
228
+ "ssl.enabled": True,
229
+ "ssl.cert_file": "certs/localhost_server.crt",
230
+ "ssl.key_file": "keys/localhost_server.key",
231
+ "ssl.ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
232
+ "ssl.verify_client": True,
233
+ "security.enabled": True,
234
+ "security.auth.enabled": True,
235
+ "security.auth.methods": ["certificate", "api_key"],
236
+ "security.auth.api_keys": {
237
+ "admin": "admin-secret-key",
238
+ "user": "user-secret-key"
239
+ },
240
+ "security.permissions.enabled": True,
241
+ "security.permissions.roles_file": "configs/roles.json",
242
+ "security.rate_limit.enabled": True,
243
+ "proxy_registration.enabled": True,
244
+ "proxy_registration.proxy_url": "http://127.0.0.1:3006",
245
+ "proxy_registration.server_id": "mcp_full_server",
246
+ "proxy_registration.server_name": "MCP Full Featured Server",
247
+ "protocols.allowed_protocols": ["http", "https", "mtls", "jsonrpc"]
248
+ })
249
+
250
+ print(f"✅ Created {10} test configurations in {self.output_dir}")
251
+
252
+
253
+ def main():
254
+ """Main entry point."""
255
+ import argparse
256
+
257
+ parser = argparse.ArgumentParser(description="Generate test configurations")
258
+ parser.add_argument(
259
+ "--comprehensive-config",
260
+ default="comprehensive_config.json",
261
+ help="Path to comprehensive configuration file"
262
+ )
263
+ parser.add_argument(
264
+ "--output-dir",
265
+ default="configs",
266
+ help="Output directory for test configurations"
267
+ )
268
+ parser.add_argument(
269
+ "--config-name",
270
+ help="Create a specific configuration (http_simple, https_auth, mtls_with_roles, etc.)"
271
+ )
272
+ parser.add_argument(
273
+ "--modifications",
274
+ help="JSON string of modifications to apply (for custom configs)"
275
+ )
276
+
277
+ args = parser.parse_args()
278
+
279
+ generator = TestConfigGenerator(args.comprehensive_config, args.output_dir)
280
+
281
+ if args.config_name:
282
+ # Create a specific configuration
283
+ if args.modifications:
284
+ modifications = json.loads(args.modifications)
285
+ else:
286
+ # Use predefined modifications
287
+ predefined = {
288
+ "http_simple": {"server.port": 8001, "ssl.enabled": False, "security.enabled": False},
289
+ "https_simple": {"server.port": 8003, "ssl.enabled": True},
290
+ "mtls_simple": {"server.port": 8005, "ssl.enabled": True, "ssl.verify_client": True},
291
+ }
292
+ modifications = predefined.get(args.config_name, {})
293
+
294
+ generator.create_config(args.config_name, modifications)
295
+ else:
296
+ # Create all test configurations
297
+ generator.create_all_test_configs()
298
+
299
+
300
+ if __name__ == "__main__":
301
+ main()
@@ -115,11 +115,7 @@ class FullTestSuiteRunner:
115
115
 
116
116
  try:
117
117
  # Run certificate generation script
118
- cmd = [
119
- sys.executable,
120
- "-m",
121
- "mcp_proxy_adapter.examples.create_certificates_simple",
122
- ]
118
+ cmd = [sys.executable, "create_certificates_simple.py"]
123
119
  self.print_info("Running certificate generation script...")
124
120
 
125
121
  result = subprocess.run(
@@ -143,29 +139,76 @@ class FullTestSuiteRunner:
143
139
  return False
144
140
 
145
141
  def generate_configurations(self) -> bool:
146
- """Generate test configurations."""
142
+ """Generate test configurations from comprehensive config."""
147
143
  self.print_step("4", "Configuration Generation")
148
144
 
149
145
  try:
150
- # Run configuration generation script
151
- cmd = [
152
- sys.executable,
153
- "-m",
154
- "mcp_proxy_adapter.examples.generate_test_configs",
155
- ]
156
- self.print_info("Running configuration generation script...")
146
+ # Check if create_test_configs.py exists
147
+ config_script = self.working_dir / "create_test_configs.py"
148
+ if not config_script.exists():
149
+ self.print_error(f"Configuration generator not found: {config_script}")
150
+ return False
151
+
152
+ # Check if comprehensive_config.json exists
153
+ comprehensive_config = self.working_dir / "comprehensive_config.json"
154
+ if not comprehensive_config.exists():
155
+ self.print_error(f"Comprehensive config not found: {comprehensive_config}")
156
+ return False
157
157
 
158
+ self.print_info("Generating test configurations from comprehensive config...")
159
+ self.print_info("This will create:")
160
+ self.print_info(" - HTTP configurations (simple and with auth)")
161
+ self.print_info(" - HTTPS configurations (simple and with auth)")
162
+ self.print_info(" - mTLS configurations (simple, with roles, with proxy registration)")
163
+ self.print_info(" - Full featured configuration (everything enabled)")
164
+
165
+ # Run the configuration generator
166
+ cmd = [sys.executable, "create_test_configs.py", "--comprehensive-config", "comprehensive_config.json"]
158
167
  result = subprocess.run(
159
168
  cmd, capture_output=True, text=True, cwd=self.working_dir
160
169
  )
161
170
 
162
171
  if result.returncode == 0:
163
- self.print_success("Configurations generated successfully")
172
+ self.print_success("Configuration generation completed successfully!")
164
173
  if result.stdout:
174
+ print("Generator output:")
165
175
  print(result.stdout)
176
+
177
+ # Create roles.json file
178
+ self.print_info("Creating roles.json file...")
179
+ roles_content = {
180
+ "roles": {
181
+ "admin": {
182
+ "permissions": ["*"],
183
+ "description": "Full administrative access"
184
+ },
185
+ "user": {
186
+ "permissions": ["read", "write"],
187
+ "description": "Standard user access"
188
+ },
189
+ "readonly": {
190
+ "permissions": ["read"],
191
+ "description": "Read-only access"
192
+ },
193
+ "guest": {
194
+ "permissions": ["read"],
195
+ "description": "Limited guest access"
196
+ }
197
+ }
198
+ }
199
+
200
+ roles_file = self.configs_dir / "roles.json"
201
+ import json
202
+ with open(roles_file, 'w', encoding='utf-8') as f:
203
+ json.dump(roles_content, f, indent=2, ensure_ascii=False)
204
+ self.print_success(f"Created roles.json: {roles_file}")
205
+
166
206
  return True
167
207
  else:
168
208
  self.print_error("Configuration generation failed!")
209
+ if result.stdout:
210
+ print("Generator output:")
211
+ print(result.stdout)
169
212
  if result.stderr:
170
213
  print("Error output:")
171
214
  print(result.stderr)
@@ -181,12 +224,7 @@ class FullTestSuiteRunner:
181
224
 
182
225
  try:
183
226
  # Run security tests
184
- cmd = [
185
- sys.executable,
186
- "-m",
187
- "mcp_proxy_adapter.examples.run_security_tests",
188
- "--verbose",
189
- ]
227
+ cmd = [sys.executable, "run_security_tests.py", "--verbose"]
190
228
  self.print_info("Running security tests...")
191
229
 
192
230
  # Debug: show current working directory and check files
@@ -235,6 +273,123 @@ class FullTestSuiteRunner:
235
273
  self.print_error(f"Failed to run security tests: {e}")
236
274
  return False
237
275
 
276
+ def run_mtls_registration_test(self) -> bool:
277
+ """Run mTLS with proxy registration test."""
278
+ self.print_step("6", "mTLS Proxy Registration Testing")
279
+
280
+ try:
281
+ # Check if test_proxy_registration.py exists
282
+ test_script = self.working_dir / "test_proxy_registration.py"
283
+ if not test_script.exists():
284
+ self.print_error(f"Test script not found: {test_script}")
285
+ return False
286
+
287
+ # Create test_proxy_registration.json config if it doesn't exist
288
+ test_config = self.configs_dir / "test_proxy_registration.json"
289
+ if not test_config.exists():
290
+ self.print_info("Creating test_proxy_registration.json configuration...")
291
+ test_config_content = {
292
+ "uuid": "550e8400-e29b-41d4-a716-446655440001",
293
+ "server": {
294
+ "host": "127.0.0.1",
295
+ "port": 20005
296
+ },
297
+ "ssl": {
298
+ "enabled": True,
299
+ "cert_file": "certs/localhost_server.crt",
300
+ "key_file": "keys/localhost_server.key",
301
+ "ca_cert": "certs/mcp_proxy_adapter_ca_ca.crt",
302
+ "client_cert_file": "certs/admin_cert.pem",
303
+ "client_key_file": "certs/admin_key.pem",
304
+ "verify_client": True
305
+ },
306
+ "registration": {
307
+ "enabled": True,
308
+ "auth_method": "token",
309
+ "server_url": "http://127.0.0.1:3006/proxy",
310
+ "token": {
311
+ "enabled": True,
312
+ "token": "proxy_registration_token_123"
313
+ },
314
+ "proxy_info": {
315
+ "name": "mcp_test_server",
316
+ "capabilities": [
317
+ "jsonrpc",
318
+ "rest",
319
+ "security",
320
+ "proxy_registration"
321
+ ],
322
+ "endpoints": {
323
+ "jsonrpc": "/api/jsonrpc",
324
+ "rest": "/cmd",
325
+ "health": "/health"
326
+ }
327
+ },
328
+ "heartbeat": {
329
+ "enabled": True,
330
+ "interval": 30
331
+ }
332
+ },
333
+ "security": {
334
+ "enabled": True,
335
+ "auth": {
336
+ "enabled": True,
337
+ "methods": [
338
+ "certificate"
339
+ ]
340
+ },
341
+ "permissions": {
342
+ "enabled": True,
343
+ "roles_file": "configs/roles.json"
344
+ }
345
+ },
346
+ "protocols": {
347
+ "enabled": True,
348
+ "default_protocol": "mtls",
349
+ "allowed_protocols": [
350
+ "https",
351
+ "mtls"
352
+ ]
353
+ }
354
+ }
355
+
356
+ import json
357
+ with open(test_config, 'w', encoding='utf-8') as f:
358
+ json.dump(test_config_content, f, indent=2)
359
+ self.print_success(f"Created test configuration: {test_config}")
360
+
361
+ self.print_info("Running mTLS proxy registration test...")
362
+ self.print_info("This test verifies:")
363
+ self.print_info(" - mTLS server startup with client certificate verification")
364
+ self.print_info(" - Proxy registration functionality")
365
+ self.print_info(" - SSL configuration validation")
366
+
367
+ # Run the test
368
+ cmd = [sys.executable, "test_proxy_registration.py"]
369
+ result = subprocess.run(
370
+ cmd, capture_output=True, text=True, cwd=self.working_dir
371
+ )
372
+
373
+ if result.returncode == 0:
374
+ self.print_success("mTLS proxy registration test completed successfully!")
375
+ if result.stdout:
376
+ print("Test output:")
377
+ print(result.stdout)
378
+ return True
379
+ else:
380
+ self.print_error("mTLS proxy registration test failed!")
381
+ if result.stdout:
382
+ print("Test output:")
383
+ print(result.stdout)
384
+ if result.stderr:
385
+ print("Error output:")
386
+ print(result.stderr)
387
+ return False
388
+
389
+ except Exception as e:
390
+ self.print_error(f"Failed to run mTLS registration test: {e}")
391
+ return False
392
+
238
393
  def cleanup(self):
239
394
  """Clean up temporary files and processes."""
240
395
  self.print_info("Cleaning up...")
@@ -305,6 +460,10 @@ class FullTestSuiteRunner:
305
460
  if not self.run_security_tests():
306
461
  return False
307
462
 
463
+ # Step 6: mTLS proxy registration testing
464
+ if not self.run_mtls_registration_test():
465
+ return False
466
+
308
467
  # All steps completed successfully
309
468
  print(f"\n{'='*60}")
310
469
  print("🎉 FULL TEST SUITE COMPLETED SUCCESSFULLY!")
@@ -315,6 +474,7 @@ class FullTestSuiteRunner:
315
474
  print("✅ Certificates generated")
316
475
  print("✅ Configurations generated")
317
476
  print("✅ Security tests passed")
477
+ print("✅ mTLS proxy registration test passed")
318
478
  print(f"\n📁 Test artifacts created in: {self.working_dir}")
319
479
  print(f"📁 Configurations: {self.configs_dir}")
320
480
  print(f"📁 Certificates: {self.certs_dir}")
@@ -2,4 +2,4 @@
2
2
  Version information for MCP Proxy Adapter.
3
3
  """
4
4
 
5
- __version__ = "6.4.10"
5
+ __version__ = "6.4.12"