mcp-proxy-adapter 6.4.43__py3-none-any.whl → 6.4.45__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 (33) hide show
  1. mcp_proxy_adapter/core/proxy_registration.py +100 -68
  2. mcp_proxy_adapter/examples/bugfix_certificate_config.py +284 -0
  3. mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
  4. mcp_proxy_adapter/examples/config_builder.py +574 -0
  5. mcp_proxy_adapter/examples/config_cli.py +283 -0
  6. mcp_proxy_adapter/examples/create_test_configs.py +169 -266
  7. mcp_proxy_adapter/examples/generate_certificates_bugfix.py +374 -0
  8. mcp_proxy_adapter/examples/generate_certificates_cli.py +406 -0
  9. mcp_proxy_adapter/examples/generate_certificates_fixed.py +313 -0
  10. mcp_proxy_adapter/examples/generate_certificates_framework.py +366 -0
  11. mcp_proxy_adapter/examples/generate_certificates_openssl.py +391 -0
  12. mcp_proxy_adapter/examples/required_certificates.py +210 -0
  13. mcp_proxy_adapter/examples/run_full_test_suite.py +117 -13
  14. mcp_proxy_adapter/examples/run_security_tests_fixed.py +41 -25
  15. mcp_proxy_adapter/examples/security_test_client.py +333 -86
  16. mcp_proxy_adapter/examples/test_config_builder.py +450 -0
  17. mcp_proxy_adapter/examples/update_config_certificates.py +136 -0
  18. mcp_proxy_adapter/version.py +1 -1
  19. {mcp_proxy_adapter-6.4.43.dist-info → mcp_proxy_adapter-6.4.45.dist-info}/METADATA +81 -1
  20. {mcp_proxy_adapter-6.4.43.dist-info → mcp_proxy_adapter-6.4.45.dist-info}/RECORD +23 -20
  21. mcp_proxy_adapter-6.4.45.dist-info/entry_points.txt +12 -0
  22. mcp_proxy_adapter/examples/create_certificates_simple.py +0 -661
  23. mcp_proxy_adapter/examples/generate_certificates.py +0 -192
  24. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +0 -515
  25. mcp_proxy_adapter/examples/generate_test_configs.py +0 -393
  26. mcp_proxy_adapter/examples/run_security_tests.py +0 -677
  27. mcp_proxy_adapter/examples/scripts/config_generator.py +0 -842
  28. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +0 -673
  29. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +0 -515
  30. mcp_proxy_adapter/examples/test_config_generator.py +0 -102
  31. mcp_proxy_adapter-6.4.43.dist-info/entry_points.txt +0 -2
  32. {mcp_proxy_adapter-6.4.43.dist-info → mcp_proxy_adapter-6.4.45.dist-info}/WHEEL +0 -0
  33. {mcp_proxy_adapter-6.4.43.dist-info → mcp_proxy_adapter-6.4.45.dist-info}/top_level.txt +0 -0
@@ -1,515 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Author: Vasiliy Zdanovskiy
4
- email: vasilyvz@gmail.com
5
- Script for generating certificates and tokens for MCP Proxy Adapter configurations.
6
- Generates all necessary certificates, keys, and tokens based on configuration requirements.
7
- Uses mcp_security_framework for certificate generation.
8
- """
9
- import json
10
- import os
11
- import sys
12
- import argparse
13
- import subprocess
14
- from pathlib import Path
15
- from typing import Dict, Any, List, Optional
16
-
17
- # Import mcp_security_framework
18
- try:
19
- from mcp_security_framework.core.cert_manager import CertificateManager
20
- from mcp_security_framework.schemas.config import (
21
- CertificateConfig,
22
- CAConfig,
23
- ServerCertConfig,
24
- ClientCertConfig,
25
- )
26
- from mcp_security_framework.schemas.models import CertificateType
27
-
28
- SECURITY_FRAMEWORK_AVAILABLE = True
29
- except ImportError:
30
- SECURITY_FRAMEWORK_AVAILABLE = False
31
- print("Warning: mcp_security_framework not available, falling back to OpenSSL")
32
-
33
-
34
- def generate_ca_certificate(output_dir: str) -> str:
35
- """
36
- Generate CA certificate and key using mcp_security_framework.
37
- Args:
38
- output_dir: Output directory for certificates
39
- Returns:
40
- Path to CA certificate file
41
- """
42
- ca_dir = os.path.join(output_dir, "certs")
43
- os.makedirs(ca_dir, exist_ok=True)
44
- if SECURITY_FRAMEWORK_AVAILABLE:
45
- try:
46
- # Configure CA certificate
47
- ca_config = CAConfig(
48
- common_name="MCP Proxy Adapter CA",
49
- organization="MCP Proxy Adapter",
50
- organizational_unit="Certificate Authority",
51
- country="US",
52
- state="State",
53
- locality="City",
54
- validity_years=10, # Используем validity_years вместо validity_days
55
- key_size=2048,
56
- hash_algorithm="sha256",
57
- )
58
- # Create certificate manager
59
- cert_config = CertificateConfig(
60
- cert_storage_path=ca_dir,
61
- key_storage_path=ca_dir,
62
- default_validity_days=3650,
63
- key_size=2048,
64
- hash_algorithm="sha256",
65
- )
66
- cert_manager = CertificateManager(cert_config)
67
- # Create CA certificate
68
- cert_pair = cert_manager.create_root_ca(ca_config)
69
- if cert_pair and cert_pair.certificate_path:
70
- print(f"✅ Generated CA certificate using mcp_security_framework")
71
- return cert_pair.certificate_path
72
- else:
73
- print(f"❌ Failed to create CA certificate: Invalid certificate pair")
74
- return None
75
- except Exception as e:
76
- print(f"❌ Error creating CA certificate with framework: {e}")
77
- return None
78
- else:
79
- # Fallback to OpenSSL
80
- ca_key = os.path.join(ca_dir, "ca.key")
81
- ca_cert = os.path.join(ca_dir, "ca.crt")
82
- # Generate CA private key
83
- subprocess.run(
84
- ["openssl", "genrsa", "-out", ca_key, "2048"],
85
- check=True,
86
- capture_output=True,
87
- )
88
- # Generate CA certificate
89
- subprocess.run(
90
- [
91
- "openssl",
92
- "req",
93
- "-new",
94
- "-x509",
95
- "-days",
96
- "365",
97
- "-key",
98
- ca_key,
99
- "-out",
100
- ca_cert,
101
- "-subj",
102
- "/C=US/ST=State/L=City/O=Organization/CN=CA",
103
- ],
104
- check=True,
105
- capture_output=True,
106
- )
107
- print(f"✅ Generated CA certificate using OpenSSL: {ca_cert}")
108
- return ca_cert
109
-
110
-
111
- def generate_server_certificate(output_dir: str, ca_cert: str) -> tuple[str, str]:
112
- """
113
- Generate server certificate and key using mcp_security_framework.
114
- Args:
115
- output_dir: Output directory for certificates
116
- ca_cert: Path to CA certificate
117
- Returns:
118
- Tuple of (certificate_path, key_path)
119
- """
120
- certs_dir = os.path.join(output_dir, "certs")
121
- keys_dir = os.path.join(output_dir, "keys")
122
- os.makedirs(certs_dir, exist_ok=True)
123
- os.makedirs(keys_dir, exist_ok=True)
124
- if SECURITY_FRAMEWORK_AVAILABLE:
125
- try:
126
- # Find CA key file
127
- ca_key = None
128
- if ca_cert.endswith(".crt"):
129
- ca_key = ca_cert.replace(".crt", ".key")
130
- elif ca_cert.endswith(".pem"):
131
- ca_key = ca_cert.replace(".pem", "_key.pem")
132
- if not os.path.exists(ca_key):
133
- print(f"❌ CA key file not found: {ca_key}")
134
- return None, None
135
- # Configure server certificate
136
- server_config = ServerCertConfig(
137
- common_name="localhost",
138
- organization="MCP Proxy Adapter",
139
- organizational_unit="Server",
140
- country="US",
141
- state="State",
142
- locality="City",
143
- validity_days=365,
144
- key_size=2048,
145
- hash_algorithm="sha256",
146
- subject_alt_names=[
147
- "localhost",
148
- "127.0.0.1",
149
- ], # Используем subject_alt_names вместо san_dns
150
- ca_cert_path=ca_cert,
151
- ca_key_path=ca_key,
152
- )
153
- # Create certificate manager
154
- cert_config = CertificateConfig(
155
- cert_storage_path=certs_dir,
156
- key_storage_path=keys_dir,
157
- default_validity_days=365,
158
- key_size=2048,
159
- hash_algorithm="sha256",
160
- )
161
- cert_manager = CertificateManager(cert_config)
162
- # Create server certificate
163
- cert_pair = cert_manager.create_server_certificate(server_config)
164
- if cert_pair and cert_pair.certificate_path and cert_pair.private_key_path:
165
- print(f"✅ Generated server certificate using mcp_security_framework")
166
- return (cert_pair.certificate_path, cert_pair.private_key_path)
167
- else:
168
- print(
169
- f"❌ Failed to create server certificate: Invalid certificate pair"
170
- )
171
- return None, None
172
- except Exception as e:
173
- print(f"❌ Error creating server certificate with framework: {e}")
174
- return None, None
175
- else:
176
- # Fallback to OpenSSL
177
- ca_key = ca_cert.replace(".crt", ".key")
178
- server_key = os.path.join(keys_dir, "server.key")
179
- server_csr = os.path.join(certs_dir, "server.csr")
180
- server_cert = os.path.join(certs_dir, "server.crt")
181
- # Generate server private key
182
- subprocess.run(
183
- ["openssl", "genrsa", "-out", server_key, "2048"],
184
- check=True,
185
- capture_output=True,
186
- )
187
- # Generate server certificate signing request
188
- subprocess.run(
189
- [
190
- "openssl",
191
- "req",
192
- "-new",
193
- "-key",
194
- server_key,
195
- "-out",
196
- server_csr,
197
- "-subj",
198
- "/C=US/ST=State/L=City/O=Organization/CN=localhost",
199
- ],
200
- check=True,
201
- capture_output=True,
202
- )
203
- # Sign server certificate with CA
204
- subprocess.run(
205
- [
206
- "openssl",
207
- "x509",
208
- "-req",
209
- "-in",
210
- server_csr,
211
- "-CA",
212
- ca_cert,
213
- "-CAkey",
214
- ca_key,
215
- "-CAcreateserial",
216
- "-out",
217
- server_cert,
218
- "-days",
219
- "365",
220
- ],
221
- check=True,
222
- capture_output=True,
223
- )
224
- # Clean up CSR
225
- os.remove(server_csr)
226
- print(f"✅ Generated server certificate using OpenSSL: {server_cert}")
227
- return server_cert, server_key
228
-
229
-
230
- def generate_client_certificate(
231
- output_dir: str,
232
- ca_cert: str,
233
- client_name: str = "client",
234
- roles: List[str] = None,
235
- permissions: List[str] = None,
236
- ) -> tuple[str, str]:
237
- """
238
- Generate client certificate and key using mcp_security_framework.
239
- Args:
240
- output_dir: Output directory for certificates
241
- ca_cert: Path to CA certificate
242
- client_name: Name of the client
243
- roles: List of roles for the client
244
- permissions: List of permissions for the client
245
- Returns:
246
- Tuple of (certificate_path, key_path)
247
- """
248
- certs_dir = os.path.join(output_dir, "certs")
249
- keys_dir = os.path.join(output_dir, "keys")
250
- os.makedirs(certs_dir, exist_ok=True)
251
- os.makedirs(keys_dir, exist_ok=True)
252
- if SECURITY_FRAMEWORK_AVAILABLE:
253
- try:
254
- # Find CA key file
255
- ca_key = None
256
- if ca_cert.endswith(".crt"):
257
- ca_key = ca_cert.replace(".crt", ".key")
258
- elif ca_cert.endswith(".pem"):
259
- ca_key = ca_cert.replace(".pem", "_key.pem")
260
- if not os.path.exists(ca_key):
261
- print(f"❌ CA key file not found: {ca_key}")
262
- return None, None
263
- # Configure client certificate
264
- client_config = ClientCertConfig(
265
- common_name=f"{client_name}-client",
266
- organization="MCP Proxy Adapter",
267
- organizational_unit="Client",
268
- country="US",
269
- state="State",
270
- locality="City",
271
- validity_days=730,
272
- key_size=2048,
273
- hash_algorithm="sha256",
274
- roles=roles or [],
275
- permissions=permissions or [],
276
- ca_cert_path=ca_cert,
277
- ca_key_path=ca_key,
278
- )
279
- # Create certificate manager
280
- cert_config = CertificateConfig(
281
- cert_storage_path=certs_dir,
282
- key_storage_path=keys_dir,
283
- default_validity_days=730,
284
- key_size=2048,
285
- hash_algorithm="sha256",
286
- )
287
- cert_manager = CertificateManager(cert_config)
288
- # Create client certificate
289
- cert_pair = cert_manager.create_client_certificate(client_config)
290
- if cert_pair and cert_pair.certificate_path and cert_pair.private_key_path:
291
- print(
292
- f"✅ Generated client certificate {client_name} using mcp_security_framework"
293
- )
294
- return (cert_pair.certificate_path, cert_pair.private_key_path)
295
- else:
296
- print(
297
- f"❌ Failed to create client certificate {client_name}: Invalid certificate pair"
298
- )
299
- return None, None
300
- except Exception as e:
301
- print(
302
- f"❌ Error creating client certificate {client_name} with framework: {e}"
303
- )
304
- return None, None
305
- else:
306
- # Fallback to OpenSSL
307
- ca_key = ca_cert.replace(".crt", ".key")
308
- client_key = os.path.join(keys_dir, f"{client_name}.key")
309
- client_csr = os.path.join(certs_dir, f"{client_name}.csr")
310
- client_cert = os.path.join(certs_dir, f"{client_name}.crt")
311
- # Generate client private key
312
- subprocess.run(
313
- ["openssl", "genrsa", "-out", client_key, "2048"],
314
- check=True,
315
- capture_output=True,
316
- )
317
- # Generate client certificate signing request
318
- subprocess.run(
319
- [
320
- "openssl",
321
- "req",
322
- "-new",
323
- "-key",
324
- client_key,
325
- "-out",
326
- client_csr,
327
- "-subj",
328
- f"/C=US/ST=State/L=City/O=Organization/CN={client_name}-client",
329
- ],
330
- check=True,
331
- capture_output=True,
332
- )
333
- # Sign client certificate with CA
334
- subprocess.run(
335
- [
336
- "openssl",
337
- "x509",
338
- "-req",
339
- "-in",
340
- client_csr,
341
- "-CA",
342
- ca_cert,
343
- "-CAkey",
344
- ca_key,
345
- "-CAcreateserial",
346
- "-out",
347
- client_cert,
348
- "-days",
349
- "730",
350
- ],
351
- check=True,
352
- capture_output=True,
353
- )
354
- # Clean up CSR
355
- os.remove(client_csr)
356
- print(
357
- f"✅ Generated client certificate {client_name} using OpenSSL: {client_cert}"
358
- )
359
- return client_cert, client_key
360
-
361
-
362
- def generate_tokens(output_dir: str) -> Dict[str, str]:
363
- """
364
- Generate API tokens for different roles.
365
- Args:
366
- output_dir: Output directory for tokens
367
- Returns:
368
- Dictionary of role -> token mappings
369
- """
370
- tokens_dir = os.path.join(output_dir, "tokens")
371
- os.makedirs(tokens_dir, exist_ok=True)
372
- tokens = {
373
- "admin": "test-token-123",
374
- "user": "user-token-456",
375
- "readonly": "readonly-token-123",
376
- "guest": "guest-token-123",
377
- "proxy": "proxy-token-123",
378
- }
379
- # Save tokens to file
380
- tokens_file = os.path.join(tokens_dir, "tokens.json")
381
- with open(tokens_file, "w") as f:
382
- json.dump(tokens, f, indent=2)
383
- print(f"✅ Generated tokens: {tokens_file}")
384
- return tokens
385
-
386
-
387
- def generate_roles_config(output_dir: str) -> Dict[str, Any]:
388
- """
389
- Generate roles configuration file.
390
- Args:
391
- output_dir: Output directory for configs
392
- Returns:
393
- Roles configuration dictionary
394
- """
395
- roles_config = {
396
- "admin": {
397
- "permissions": [
398
- "read",
399
- "write",
400
- "execute",
401
- "delete",
402
- "admin",
403
- "register",
404
- "unregister",
405
- "heartbeat",
406
- "discover",
407
- ],
408
- "tokens": [],
409
- },
410
- "user": {
411
- "permissions": [
412
- "read",
413
- "execute",
414
- "register",
415
- "unregister",
416
- "heartbeat",
417
- "discover",
418
- ],
419
- "tokens": [],
420
- },
421
- "readonly": {"permissions": ["read", "discover"], "tokens": []},
422
- "guest": {"permissions": ["read", "discover"], "tokens": []},
423
- "proxy": {
424
- "permissions": ["register", "unregister", "heartbeat", "discover"],
425
- "tokens": [],
426
- },
427
- }
428
- # Save roles config to file
429
- roles_file = os.path.join(output_dir, "roles.json")
430
- with open(roles_file, "w") as f:
431
- json.dump(roles_config, f, indent=2)
432
- print(f"✅ Generated roles configuration: {roles_file}")
433
- return roles_config
434
-
435
-
436
- def main():
437
- """Main function for certificate and token generation."""
438
- parser = argparse.ArgumentParser(description="Generate certificates and tokens")
439
- parser.add_argument(
440
- "--output-dir", "-o", default="./certs", help="Output directory"
441
- )
442
- parser.add_argument(
443
- "--framework", action="store_true", help="Use mcp_security_framework"
444
- )
445
- args = parser.parse_args()
446
- print("🔐 Certificate and Token Generation Script")
447
- print("=" * 50)
448
- if args.framework and not SECURITY_FRAMEWORK_AVAILABLE:
449
- print("❌ mcp_security_framework not available")
450
- return 1
451
- # Create output directory
452
- os.makedirs(args.output_dir, exist_ok=True)
453
- try:
454
- # 1. Generate CA certificate
455
- print("\n🔧 Generating CA certificate...")
456
- ca_cert = generate_ca_certificate(args.output_dir)
457
- if not ca_cert:
458
- print("❌ Failed to generate CA certificate")
459
- return 1
460
- # 2. Generate server certificate
461
- print("\n🔧 Generating server certificate...")
462
- server_cert, server_key = generate_server_certificate(args.output_dir, ca_cert)
463
- if not server_cert or not server_key:
464
- print("❌ Failed to generate server certificate")
465
- return 1
466
- # 3. Generate client certificates
467
- print("\n🔧 Generating client certificates...")
468
- client_configs = [
469
- (
470
- "admin",
471
- ["admin"],
472
- [
473
- "read",
474
- "write",
475
- "execute",
476
- "delete",
477
- "admin",
478
- "register",
479
- "unregister",
480
- "heartbeat",
481
- "discover",
482
- ],
483
- ),
484
- (
485
- "user",
486
- ["user"],
487
- ["read", "execute", "register", "unregister", "heartbeat", "discover"],
488
- ),
489
- ("readonly", ["readonly"], ["read", "discover"]),
490
- ("guest", ["guest"], ["read", "discover"]),
491
- ("proxy", ["proxy"], ["register", "unregister", "heartbeat", "discover"]),
492
- ]
493
- for client_name, roles, permissions in client_configs:
494
- client_cert, client_key = generate_client_certificate(
495
- args.output_dir, ca_cert, client_name, roles, permissions
496
- )
497
- if not client_cert or not client_key:
498
- print(f"❌ Failed to generate client certificate {client_name}")
499
- return 1
500
- # 4. Generate tokens
501
- print("\n🔧 Generating tokens...")
502
- tokens = generate_tokens(args.output_dir)
503
- # 5. Generate roles configuration
504
- print("\n🔧 Generating roles configuration...")
505
- roles_config = generate_roles_config(args.output_dir)
506
- print("\n🎉 All certificates and tokens generated successfully!")
507
- print(f"📁 Output directory: {args.output_dir}")
508
- return 0
509
- except Exception as e:
510
- print(f"❌ Error during generation: {e}")
511
- return 1
512
-
513
-
514
- if __name__ == "__main__":
515
- exit(main())
@@ -1,102 +0,0 @@
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
-
11
- # Add the project root to the path
12
- project_root = Path(__file__).parent.parent.parent
13
- sys.path.insert(0, str(project_root))
14
- from mcp_proxy_adapter.utils.config_generator import ConfigGenerator
15
-
16
-
17
- def test_config_generator():
18
- """Test the configuration generator with different types."""
19
- generator = ConfigGenerator()
20
- # Test configuration types
21
- config_types = [
22
- "basic_http",
23
- "http_token",
24
- "https",
25
- "https_token",
26
- "https_no_protocol_middleware",
27
- "mtls",
28
- "mtls_no_protocol_middleware",
29
- ]
30
- print("Testing Configuration Generator")
31
- print("=" * 50)
32
- for config_type in config_types:
33
- print(f"\nTesting {config_type} configuration:")
34
- print("-" * 30)
35
- try:
36
- # Generate configuration
37
- config = generator._get_config_by_type(config_type)
38
- # Check if protocols section exists
39
- if "protocols" in config:
40
- protocols = config["protocols"]
41
- print(f"✅ Protocols section found:")
42
- print(f" - enabled: {protocols.get('enabled', 'NOT SET')}")
43
- print(
44
- f" - allowed_protocols: {protocols.get('allowed_protocols', 'NOT SET')}"
45
- )
46
- print(
47
- f" - default_protocol: {protocols.get('default_protocol', 'NOT SET')}"
48
- )
49
- else:
50
- print("❌ Protocols section missing!")
51
- # Check SSL configuration
52
- ssl_enabled = config.get("ssl", {}).get("enabled", False)
53
- security_ssl_enabled = (
54
- config.get("security", {}).get("ssl", {}).get("enabled", False)
55
- )
56
- print(f" - legacy ssl.enabled: {ssl_enabled}")
57
- print(f" - security.ssl.enabled: {security_ssl_enabled}")
58
- # Check if configuration is valid for its type
59
- if (
60
- config_type == "https_no_protocol_middleware"
61
- or config_type == "mtls_no_protocol_middleware"
62
- ):
63
- if protocols.get("enabled") == False:
64
- print("✅ ProtocolMiddleware correctly disabled")
65
- else:
66
- print("❌ ProtocolMiddleware should be disabled but is enabled")
67
- else:
68
- if protocols.get("enabled") == True:
69
- print("✅ ProtocolMiddleware correctly enabled")
70
- else:
71
- print("❌ ProtocolMiddleware should be enabled but is disabled")
72
- # Save configuration to file for inspection
73
- output_file = f"test_config_{config_type}.json"
74
- with open(output_file, "w") as f:
75
- json.dump(config, f, indent=2)
76
- print(f" - Configuration saved to {output_file}")
77
- except Exception as e:
78
- print(f"❌ Error generating {config_type} configuration: {e}")
79
- print("\n" + "=" * 50)
80
- print("Configuration generator test completed!")
81
-
82
-
83
- def test_config_with_comments():
84
- """Test configuration generation with comments."""
85
- generator = ConfigGenerator()
86
- print("\nTesting configuration with comments:")
87
- print("-" * 40)
88
- try:
89
- # Generate HTTPS configuration with comments
90
- commented_config = generator.generate_config_with_comments("https")
91
- print("✅ HTTPS configuration with comments generated successfully")
92
- # Save to file
93
- with open("test_https_with_comments.json", "w") as f:
94
- f.write(commented_config)
95
- print(" - Configuration saved to test_https_with_comments.json")
96
- except Exception as e:
97
- print(f"❌ Error generating configuration with comments: {e}")
98
-
99
-
100
- if __name__ == "__main__":
101
- test_config_generator()
102
- test_config_with_comments()
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- mcp-proxy-adapter = mcp_proxy_adapter.__main__:main