mcp-proxy-adapter 6.1.1__py3-none-any.whl → 6.2.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 (146) hide show
  1. mcp_proxy_adapter/__main__.py +27 -7
  2. mcp_proxy_adapter/api/app.py +18 -7
  3. mcp_proxy_adapter/commands/ssl_setup_command.py +234 -351
  4. mcp_proxy_adapter/core/app_factory.py +87 -3
  5. mcp_proxy_adapter/core/app_runner.py +272 -0
  6. mcp_proxy_adapter/core/certificate_utils.py +291 -73
  7. mcp_proxy_adapter/core/client.py +574 -0
  8. mcp_proxy_adapter/core/client_manager.py +284 -0
  9. mcp_proxy_adapter/core/server_adapter.py +17 -80
  10. mcp_proxy_adapter/core/server_engine.py +5 -99
  11. mcp_proxy_adapter/core/ssl_utils.py +13 -12
  12. mcp_proxy_adapter/core/transport_manager.py +5 -5
  13. mcp_proxy_adapter/examples/__init__.py +16 -0
  14. mcp_proxy_adapter/examples/basic_framework/__init__.py +7 -0
  15. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  16. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  17. mcp_proxy_adapter/examples/basic_framework/main.py +21 -40
  18. mcp_proxy_adapter/examples/commands/__init__.py +5 -1
  19. mcp_proxy_adapter/examples/create_certificates_simple.py +260 -75
  20. mcp_proxy_adapter/examples/debug_request_state.py +4 -36
  21. mcp_proxy_adapter/examples/debug_role_chain.py +2 -49
  22. mcp_proxy_adapter/examples/demo_client.py +0 -66
  23. mcp_proxy_adapter/examples/full_application/__init__.py +11 -0
  24. mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
  25. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -19
  26. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -16
  27. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
  28. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -22
  29. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -24
  30. mcp_proxy_adapter/examples/full_application/main.py +65 -44
  31. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
  32. mcp_proxy_adapter/examples/generate_all_certificates.py +0 -67
  33. mcp_proxy_adapter/examples/generate_certificates.py +0 -15
  34. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
  35. mcp_proxy_adapter/examples/generate_test_configs.py +204 -0
  36. mcp_proxy_adapter/examples/proxy_registration_example.py +3 -70
  37. mcp_proxy_adapter/examples/run_example.py +1 -23
  38. mcp_proxy_adapter/examples/run_security_tests.py +2 -60
  39. mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -53
  40. mcp_proxy_adapter/examples/security_test_client.py +18 -123
  41. mcp_proxy_adapter/examples/setup_test_environment.py +179 -0
  42. mcp_proxy_adapter/examples/test_config.py +148 -0
  43. mcp_proxy_adapter/examples/test_config_generator.py +1 -25
  44. mcp_proxy_adapter/examples/test_examples.py +4 -67
  45. mcp_proxy_adapter/examples/universal_client.py +154 -162
  46. mcp_proxy_adapter/main.py +51 -161
  47. mcp_proxy_adapter/version.py +1 -1
  48. mcp_proxy_adapter-6.2.1.dist-info/METADATA +676 -0
  49. mcp_proxy_adapter-6.2.1.dist-info/RECORD +119 -0
  50. mcp_proxy_adapter/docs/EN/TROUBLESHOOTING.md +0 -285
  51. mcp_proxy_adapter/docs/RU/TROUBLESHOOTING.md +0 -285
  52. mcp_proxy_adapter/examples/README.md +0 -257
  53. mcp_proxy_adapter/examples/README_EN.md +0 -258
  54. mcp_proxy_adapter/examples/SECURITY_TESTING.md +0 -455
  55. mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +0 -37
  56. mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +0 -23
  57. mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +0 -43
  58. mcp_proxy_adapter/examples/basic_framework/configs/https_no_protocol_middleware.json +0 -36
  59. mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +0 -29
  60. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_protocol_middleware.json +0 -34
  61. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +0 -39
  62. mcp_proxy_adapter/examples/basic_framework/configs/mtls_simple.json +0 -35
  63. mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +0 -45
  64. mcp_proxy_adapter/examples/basic_framework/roles.json +0 -21
  65. mcp_proxy_adapter/examples/cert_config.json +0 -9
  66. mcp_proxy_adapter/examples/certs/admin.crt +0 -32
  67. mcp_proxy_adapter/examples/certs/admin.key +0 -52
  68. mcp_proxy_adapter/examples/certs/admin_cert.pem +0 -21
  69. mcp_proxy_adapter/examples/certs/admin_key.pem +0 -28
  70. mcp_proxy_adapter/examples/certs/ca_cert.pem +0 -23
  71. mcp_proxy_adapter/examples/certs/ca_cert.srl +0 -1
  72. mcp_proxy_adapter/examples/certs/ca_key.pem +0 -28
  73. mcp_proxy_adapter/examples/certs/cert_config.json +0 -9
  74. mcp_proxy_adapter/examples/certs/client.crt +0 -32
  75. mcp_proxy_adapter/examples/certs/client.key +0 -52
  76. mcp_proxy_adapter/examples/certs/client_admin.crt +0 -32
  77. mcp_proxy_adapter/examples/certs/client_admin.key +0 -52
  78. mcp_proxy_adapter/examples/certs/client_user.crt +0 -32
  79. mcp_proxy_adapter/examples/certs/client_user.key +0 -52
  80. mcp_proxy_adapter/examples/certs/guest_cert.pem +0 -21
  81. mcp_proxy_adapter/examples/certs/guest_key.pem +0 -28
  82. mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +0 -23
  83. mcp_proxy_adapter/examples/certs/proxy_cert.pem +0 -21
  84. mcp_proxy_adapter/examples/certs/proxy_key.pem +0 -28
  85. mcp_proxy_adapter/examples/certs/readonly.crt +0 -32
  86. mcp_proxy_adapter/examples/certs/readonly.key +0 -52
  87. mcp_proxy_adapter/examples/certs/readonly_cert.pem +0 -21
  88. mcp_proxy_adapter/examples/certs/readonly_key.pem +0 -28
  89. mcp_proxy_adapter/examples/certs/server.crt +0 -32
  90. mcp_proxy_adapter/examples/certs/server.key +0 -52
  91. mcp_proxy_adapter/examples/certs/server_cert.pem +0 -32
  92. mcp_proxy_adapter/examples/certs/server_key.pem +0 -52
  93. mcp_proxy_adapter/examples/certs/test_ca_ca.crt +0 -20
  94. mcp_proxy_adapter/examples/certs/user.crt +0 -32
  95. mcp_proxy_adapter/examples/certs/user.key +0 -52
  96. mcp_proxy_adapter/examples/certs/user_cert.pem +0 -21
  97. mcp_proxy_adapter/examples/certs/user_key.pem +0 -28
  98. mcp_proxy_adapter/examples/client_configs/api_key_client.json +0 -13
  99. mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +0 -13
  100. mcp_proxy_adapter/examples/client_configs/certificate_client.json +0 -22
  101. mcp_proxy_adapter/examples/client_configs/jwt_client.json +0 -15
  102. mcp_proxy_adapter/examples/client_configs/no_auth_client.json +0 -9
  103. mcp_proxy_adapter/examples/full_application/configs/http_auth.json +0 -37
  104. mcp_proxy_adapter/examples/full_application/configs/http_simple.json +0 -23
  105. mcp_proxy_adapter/examples/full_application/configs/https_auth.json +0 -39
  106. mcp_proxy_adapter/examples/full_application/configs/https_simple.json +0 -25
  107. mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +0 -39
  108. mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +0 -45
  109. mcp_proxy_adapter/examples/full_application/roles.json +0 -21
  110. mcp_proxy_adapter/examples/keys/ca_key.pem +0 -28
  111. mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +0 -28
  112. mcp_proxy_adapter/examples/keys/test_ca_ca.key +0 -28
  113. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +0 -220
  114. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +0 -1
  115. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +0 -1
  116. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +0 -1
  117. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +0 -1
  118. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +0 -1
  119. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +0 -220
  120. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +0 -1
  121. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +0 -1
  122. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +0 -1
  123. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +0 -1
  124. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +0 -1
  125. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +0 -2
  126. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +0 -1
  127. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +0 -1
  128. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +0 -1
  129. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +0 -1
  130. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +0 -1
  131. mcp_proxy_adapter/examples/roles.json +0 -38
  132. mcp_proxy_adapter/examples/server_configs/config_basic_http.json +0 -204
  133. mcp_proxy_adapter/examples/server_configs/config_http_token.json +0 -238
  134. mcp_proxy_adapter/examples/server_configs/config_https.json +0 -215
  135. mcp_proxy_adapter/examples/server_configs/config_https_token.json +0 -231
  136. mcp_proxy_adapter/examples/server_configs/config_mtls.json +0 -215
  137. mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +0 -250
  138. mcp_proxy_adapter/examples/server_configs/config_simple.json +0 -46
  139. mcp_proxy_adapter/examples/server_configs/roles.json +0 -38
  140. mcp_proxy_adapter/utils/config_generator.py +0 -727
  141. mcp_proxy_adapter-6.1.1.dist-info/METADATA +0 -205
  142. mcp_proxy_adapter-6.1.1.dist-info/RECORD +0 -197
  143. mcp_proxy_adapter-6.1.1.dist-info/entry_points.txt +0 -2
  144. mcp_proxy_adapter-6.1.1.dist-info/licenses/LICENSE +0 -21
  145. {mcp_proxy_adapter-6.1.1.dist-info → mcp_proxy_adapter-6.2.1.dist-info}/WHEEL +0 -0
  146. {mcp_proxy_adapter-6.1.1.dist-info → mcp_proxy_adapter-6.2.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,369 @@
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
+ # Import mcp_security_framework
17
+ try:
18
+ from mcp_security_framework.core.cert_manager import CertificateManager
19
+ from mcp_security_framework.schemas.config import CertificateConfig, CAConfig, ServerCertConfig, ClientCertConfig
20
+ from mcp_security_framework.schemas.models import CertificateType
21
+ SECURITY_FRAMEWORK_AVAILABLE = True
22
+ except ImportError:
23
+ SECURITY_FRAMEWORK_AVAILABLE = False
24
+ print("Warning: mcp_security_framework not available, falling back to OpenSSL")
25
+ def generate_ca_certificate(output_dir: str) -> str:
26
+ """
27
+ Generate CA certificate and key using mcp_security_framework.
28
+ Args:
29
+ output_dir: Output directory for certificates
30
+ Returns:
31
+ Path to CA certificate file
32
+ """
33
+ ca_dir = os.path.join(output_dir, "certs")
34
+ os.makedirs(ca_dir, exist_ok=True)
35
+ if SECURITY_FRAMEWORK_AVAILABLE:
36
+ try:
37
+ # Configure CA certificate
38
+ ca_config = CAConfig(
39
+ common_name="MCP Proxy Adapter CA",
40
+ organization="MCP Proxy Adapter",
41
+ organizational_unit="Certificate Authority",
42
+ country="US",
43
+ state="State",
44
+ locality="City",
45
+ validity_years=10, # Используем validity_years вместо validity_days
46
+ key_size=2048,
47
+ hash_algorithm="sha256"
48
+ )
49
+ # Create certificate manager
50
+ cert_config = CertificateConfig(
51
+ cert_storage_path=ca_dir,
52
+ key_storage_path=ca_dir,
53
+ default_validity_days=3650,
54
+ key_size=2048,
55
+ hash_algorithm="sha256"
56
+ )
57
+ cert_manager = CertificateManager(cert_config)
58
+ # Create CA certificate
59
+ cert_pair = cert_manager.create_root_ca(ca_config)
60
+ if cert_pair and cert_pair.certificate_path:
61
+ print(f"✅ Generated CA certificate using mcp_security_framework")
62
+ return cert_pair.certificate_path
63
+ else:
64
+ print(f"❌ Failed to create CA certificate: Invalid certificate pair")
65
+ return None
66
+ except Exception as e:
67
+ print(f"❌ Error creating CA certificate with framework: {e}")
68
+ return None
69
+ else:
70
+ # Fallback to OpenSSL
71
+ ca_key = os.path.join(ca_dir, "ca.key")
72
+ ca_cert = os.path.join(ca_dir, "ca.crt")
73
+ # Generate CA private key
74
+ subprocess.run([
75
+ "openssl", "genrsa", "-out", ca_key, "2048"
76
+ ], check=True, capture_output=True)
77
+ # Generate CA certificate
78
+ subprocess.run([
79
+ "openssl", "req", "-new", "-x509", "-days", "365", "-key", ca_key,
80
+ "-out", ca_cert, "-subj", "/C=US/ST=State/L=City/O=Organization/CN=CA"
81
+ ], check=True, capture_output=True)
82
+ print(f"✅ Generated CA certificate using OpenSSL: {ca_cert}")
83
+ return ca_cert
84
+ def generate_server_certificate(output_dir: str, ca_cert: str) -> tuple[str, str]:
85
+ """
86
+ Generate server certificate and key using mcp_security_framework.
87
+ Args:
88
+ output_dir: Output directory for certificates
89
+ ca_cert: Path to CA certificate
90
+ Returns:
91
+ Tuple of (certificate_path, key_path)
92
+ """
93
+ certs_dir = os.path.join(output_dir, "certs")
94
+ keys_dir = os.path.join(output_dir, "keys")
95
+ os.makedirs(certs_dir, exist_ok=True)
96
+ os.makedirs(keys_dir, exist_ok=True)
97
+ if SECURITY_FRAMEWORK_AVAILABLE:
98
+ try:
99
+ # Find CA key file
100
+ ca_key = None
101
+ if ca_cert.endswith('.crt'):
102
+ ca_key = ca_cert.replace('.crt', '.key')
103
+ elif ca_cert.endswith('.pem'):
104
+ ca_key = ca_cert.replace('.pem', '_key.pem')
105
+ if not os.path.exists(ca_key):
106
+ print(f"❌ CA key file not found: {ca_key}")
107
+ return None, None
108
+ # Configure server certificate
109
+ server_config = ServerCertConfig(
110
+ common_name="localhost",
111
+ organization="MCP Proxy Adapter",
112
+ organizational_unit="Server",
113
+ country="US",
114
+ state="State",
115
+ locality="City",
116
+ validity_days=365,
117
+ key_size=2048,
118
+ hash_algorithm="sha256",
119
+ subject_alt_names=["localhost", "127.0.0.1"], # Используем subject_alt_names вместо san_dns
120
+ ca_cert_path=ca_cert,
121
+ ca_key_path=ca_key
122
+ )
123
+ # Create certificate manager
124
+ cert_config = CertificateConfig(
125
+ cert_storage_path=certs_dir,
126
+ key_storage_path=keys_dir,
127
+ default_validity_days=365,
128
+ key_size=2048,
129
+ hash_algorithm="sha256"
130
+ )
131
+ cert_manager = CertificateManager(cert_config)
132
+ # Create server certificate
133
+ cert_pair = cert_manager.create_server_certificate(server_config)
134
+ if cert_pair and cert_pair.certificate_path and cert_pair.private_key_path:
135
+ print(f"✅ Generated server certificate using mcp_security_framework")
136
+ return (cert_pair.certificate_path, cert_pair.private_key_path)
137
+ else:
138
+ print(f"❌ Failed to create server certificate: Invalid certificate pair")
139
+ return None, None
140
+ except Exception as e:
141
+ print(f"❌ Error creating server certificate with framework: {e}")
142
+ return None, None
143
+ else:
144
+ # Fallback to OpenSSL
145
+ ca_key = ca_cert.replace(".crt", ".key")
146
+ server_key = os.path.join(keys_dir, "server.key")
147
+ server_csr = os.path.join(certs_dir, "server.csr")
148
+ server_cert = os.path.join(certs_dir, "server.crt")
149
+ # Generate server private key
150
+ subprocess.run([
151
+ "openssl", "genrsa", "-out", server_key, "2048"
152
+ ], check=True, capture_output=True)
153
+ # Generate server certificate signing request
154
+ subprocess.run([
155
+ "openssl", "req", "-new", "-key", server_key, "-out", server_csr,
156
+ "-subj", "/C=US/ST=State/L=City/O=Organization/CN=localhost"
157
+ ], check=True, capture_output=True)
158
+ # Sign server certificate with CA
159
+ subprocess.run([
160
+ "openssl", "x509", "-req", "-in", server_csr, "-CA", ca_cert,
161
+ "-CAkey", ca_key, "-CAcreateserial", "-out", server_cert, "-days", "365"
162
+ ], check=True, capture_output=True)
163
+ # Clean up CSR
164
+ os.remove(server_csr)
165
+ print(f"✅ Generated server certificate using OpenSSL: {server_cert}")
166
+ return server_cert, server_key
167
+ def generate_client_certificate(output_dir: str, ca_cert: str, client_name: str = "client",
168
+ roles: List[str] = None, permissions: List[str] = None) -> tuple[str, str]:
169
+ """
170
+ Generate client certificate and key using mcp_security_framework.
171
+ Args:
172
+ output_dir: Output directory for certificates
173
+ ca_cert: Path to CA certificate
174
+ client_name: Name of the client
175
+ roles: List of roles for the client
176
+ permissions: List of permissions for the client
177
+ Returns:
178
+ Tuple of (certificate_path, key_path)
179
+ """
180
+ certs_dir = os.path.join(output_dir, "certs")
181
+ keys_dir = os.path.join(output_dir, "keys")
182
+ os.makedirs(certs_dir, exist_ok=True)
183
+ os.makedirs(keys_dir, exist_ok=True)
184
+ if SECURITY_FRAMEWORK_AVAILABLE:
185
+ try:
186
+ # Find CA key file
187
+ ca_key = None
188
+ if ca_cert.endswith('.crt'):
189
+ ca_key = ca_cert.replace('.crt', '.key')
190
+ elif ca_cert.endswith('.pem'):
191
+ ca_key = ca_cert.replace('.pem', '_key.pem')
192
+ if not os.path.exists(ca_key):
193
+ print(f"❌ CA key file not found: {ca_key}")
194
+ return None, None
195
+ # Configure client certificate
196
+ client_config = ClientCertConfig(
197
+ common_name=f"{client_name}-client",
198
+ organization="MCP Proxy Adapter",
199
+ organizational_unit="Client",
200
+ country="US",
201
+ state="State",
202
+ locality="City",
203
+ validity_days=730,
204
+ key_size=2048,
205
+ hash_algorithm="sha256",
206
+ roles=roles or [],
207
+ permissions=permissions or [],
208
+ ca_cert_path=ca_cert,
209
+ ca_key_path=ca_key
210
+ )
211
+ # Create certificate manager
212
+ cert_config = CertificateConfig(
213
+ cert_storage_path=certs_dir,
214
+ key_storage_path=keys_dir,
215
+ default_validity_days=730,
216
+ key_size=2048,
217
+ hash_algorithm="sha256"
218
+ )
219
+ cert_manager = CertificateManager(cert_config)
220
+ # Create client certificate
221
+ cert_pair = cert_manager.create_client_certificate(client_config)
222
+ if cert_pair and cert_pair.certificate_path and cert_pair.private_key_path:
223
+ print(f"✅ Generated client certificate {client_name} using mcp_security_framework")
224
+ return (cert_pair.certificate_path, cert_pair.private_key_path)
225
+ else:
226
+ print(f"❌ Failed to create client certificate {client_name}: Invalid certificate pair")
227
+ return None, None
228
+ except Exception as e:
229
+ print(f"❌ Error creating client certificate {client_name} with framework: {e}")
230
+ return None, None
231
+ else:
232
+ # Fallback to OpenSSL
233
+ ca_key = ca_cert.replace(".crt", ".key")
234
+ client_key = os.path.join(keys_dir, f"{client_name}.key")
235
+ client_csr = os.path.join(certs_dir, f"{client_name}.csr")
236
+ client_cert = os.path.join(certs_dir, f"{client_name}.crt")
237
+ # Generate client private key
238
+ subprocess.run([
239
+ "openssl", "genrsa", "-out", client_key, "2048"
240
+ ], check=True, capture_output=True)
241
+ # Generate client certificate signing request
242
+ subprocess.run([
243
+ "openssl", "req", "-new", "-key", client_key, "-out", client_csr,
244
+ "-subj", f"/C=US/ST=State/L=City/O=Organization/CN={client_name}-client"
245
+ ], check=True, capture_output=True)
246
+ # Sign client certificate with CA
247
+ subprocess.run([
248
+ "openssl", "x509", "-req", "-in", client_csr, "-CA", ca_cert,
249
+ "-CAkey", ca_key, "-CAcreateserial", "-out", client_cert, "-days", "730"
250
+ ], check=True, capture_output=True)
251
+ # Clean up CSR
252
+ os.remove(client_csr)
253
+ print(f"✅ Generated client certificate {client_name} using OpenSSL: {client_cert}")
254
+ return client_cert, client_key
255
+ def generate_tokens(output_dir: str) -> Dict[str, str]:
256
+ """
257
+ Generate API tokens for different roles.
258
+ Args:
259
+ output_dir: Output directory for tokens
260
+ Returns:
261
+ Dictionary of role -> token mappings
262
+ """
263
+ tokens_dir = os.path.join(output_dir, "tokens")
264
+ os.makedirs(tokens_dir, exist_ok=True)
265
+ tokens = {
266
+ "admin": "test-token-123",
267
+ "user": "user-token-456",
268
+ "readonly": "readonly-token-123",
269
+ "guest": "guest-token-123",
270
+ "proxy": "proxy-token-123"
271
+ }
272
+ # Save tokens to file
273
+ tokens_file = os.path.join(tokens_dir, "tokens.json")
274
+ with open(tokens_file, 'w') as f:
275
+ json.dump(tokens, f, indent=2)
276
+ print(f"✅ Generated tokens: {tokens_file}")
277
+ return tokens
278
+ def generate_roles_config(output_dir: str) -> Dict[str, Any]:
279
+ """
280
+ Generate roles configuration file.
281
+ Args:
282
+ output_dir: Output directory for configs
283
+ Returns:
284
+ Roles configuration dictionary
285
+ """
286
+ roles_config = {
287
+ "admin": {
288
+ "permissions": ["read", "write", "execute", "delete", "admin", "register", "unregister", "heartbeat", "discover"],
289
+ "tokens": []
290
+ },
291
+ "user": {
292
+ "permissions": ["read", "execute", "register", "unregister", "heartbeat", "discover"],
293
+ "tokens": []
294
+ },
295
+ "readonly": {
296
+ "permissions": ["read", "discover"],
297
+ "tokens": []
298
+ },
299
+ "guest": {
300
+ "permissions": ["read", "discover"],
301
+ "tokens": []
302
+ },
303
+ "proxy": {
304
+ "permissions": ["register", "unregister", "heartbeat", "discover"],
305
+ "tokens": []
306
+ }
307
+ }
308
+ # Save roles config to file
309
+ roles_file = os.path.join(output_dir, "roles.json")
310
+ with open(roles_file, 'w') as f:
311
+ json.dump(roles_config, f, indent=2)
312
+ print(f"✅ Generated roles configuration: {roles_file}")
313
+ return roles_config
314
+ def main():
315
+ """Main function for certificate and token generation."""
316
+ parser = argparse.ArgumentParser(description="Generate certificates and tokens")
317
+ parser.add_argument("--output-dir", "-o", default="./certs", help="Output directory")
318
+ parser.add_argument("--framework", action="store_true", help="Use mcp_security_framework")
319
+ args = parser.parse_args()
320
+ print("🔐 Certificate and Token Generation Script")
321
+ print("=" * 50)
322
+ if args.framework and not SECURITY_FRAMEWORK_AVAILABLE:
323
+ print("❌ mcp_security_framework not available")
324
+ return 1
325
+ # Create output directory
326
+ os.makedirs(args.output_dir, exist_ok=True)
327
+ try:
328
+ # 1. Generate CA certificate
329
+ print("\n🔧 Generating CA certificate...")
330
+ ca_cert = generate_ca_certificate(args.output_dir)
331
+ if not ca_cert:
332
+ print("❌ Failed to generate CA certificate")
333
+ return 1
334
+ # 2. Generate server certificate
335
+ print("\n🔧 Generating server certificate...")
336
+ server_cert, server_key = generate_server_certificate(args.output_dir, ca_cert)
337
+ if not server_cert or not server_key:
338
+ print("❌ Failed to generate server certificate")
339
+ return 1
340
+ # 3. Generate client certificates
341
+ print("\n🔧 Generating client certificates...")
342
+ client_configs = [
343
+ ("admin", ["admin"], ["read", "write", "execute", "delete", "admin", "register", "unregister", "heartbeat", "discover"]),
344
+ ("user", ["user"], ["read", "execute", "register", "unregister", "heartbeat", "discover"]),
345
+ ("readonly", ["readonly"], ["read", "discover"]),
346
+ ("guest", ["guest"], ["read", "discover"]),
347
+ ("proxy", ["proxy"], ["register", "unregister", "heartbeat", "discover"])
348
+ ]
349
+ for client_name, roles, permissions in client_configs:
350
+ client_cert, client_key = generate_client_certificate(
351
+ args.output_dir, ca_cert, client_name, roles, permissions
352
+ )
353
+ if not client_cert or not client_key:
354
+ print(f"❌ Failed to generate client certificate {client_name}")
355
+ return 1
356
+ # 4. Generate tokens
357
+ print("\n🔧 Generating tokens...")
358
+ tokens = generate_tokens(args.output_dir)
359
+ # 5. Generate roles configuration
360
+ print("\n🔧 Generating roles configuration...")
361
+ roles_config = generate_roles_config(args.output_dir)
362
+ print("\n🎉 All certificates and tokens generated successfully!")
363
+ print(f"📁 Output directory: {args.output_dir}")
364
+ return 0
365
+ except Exception as e:
366
+ print(f"❌ Error during generation: {e}")
367
+ return 1
368
+ if __name__ == "__main__":
369
+ exit(main())
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Author: Vasiliy Zdanovskiy
4
+ email: vasilyvz@gmail.com
5
+ Script for generating test configurations for MCP Proxy Adapter.
6
+ Generates 6 different configuration types for testing various security scenarios.
7
+ """
8
+ import json
9
+ import os
10
+ import argparse
11
+ from typing import Dict, Any
12
+ def generate_http_simple_config(port: int = 8000) -> Dict[str, Any]:
13
+ """Generate HTTP configuration without authorization."""
14
+ return {
15
+ "server": {"host": "127.0.0.1", "port": port},
16
+ "ssl": {"enabled": False},
17
+ "security": {"enabled": False},
18
+ "protocols": {"enabled": True, "allowed_protocols": ["http"]}
19
+ }
20
+ def generate_http_token_config(port: int = 8001) -> Dict[str, Any]:
21
+ """Generate HTTP configuration with token authorization."""
22
+ return {
23
+ "server": {"host": "127.0.0.1", "port": port},
24
+ "ssl": {"enabled": False},
25
+ "security": {
26
+ "enabled": True,
27
+ "auth": {"enabled": True, "methods": ["api_key"]},
28
+ "permissions": {"enabled": True, "roles_file": "./roles.json"}
29
+ },
30
+ "protocols": {"enabled": True, "allowed_protocols": ["http"]}
31
+ }
32
+ def generate_https_simple_config(port: int = 8002) -> Dict[str, Any]:
33
+ """Generate HTTPS configuration without client certificate verification and authorization."""
34
+ return {
35
+ "server": {"host": "127.0.0.1", "port": port},
36
+ "ssl": {
37
+ "enabled": True,
38
+ "cert_file": "./certs/server_cert.pem",
39
+ "key_file": "./certs/server_key.pem"
40
+ },
41
+ "security": {"enabled": False},
42
+ "protocols": {"enabled": True, "allowed_protocols": ["http", "https"]}
43
+ }
44
+ def generate_https_token_config(port: int = 8003) -> Dict[str, Any]:
45
+ """Generate HTTPS configuration without client certificate verification with token authorization."""
46
+ return {
47
+ "server": {"host": "127.0.0.1", "port": port},
48
+ "ssl": {
49
+ "enabled": True,
50
+ "cert_file": "./certs/server_cert.pem",
51
+ "key_file": "./certs/server_key.pem"
52
+ },
53
+ "security": {
54
+ "enabled": True,
55
+ "auth": {"enabled": True, "methods": ["api_key"]},
56
+ "permissions": {"enabled": True, "roles_file": "./roles.json"}
57
+ },
58
+ "protocols": {"enabled": True, "allowed_protocols": ["http", "https"]}
59
+ }
60
+ def generate_mtls_no_roles_config(port: int = 8004) -> Dict[str, Any]:
61
+ """Generate mTLS configuration without roles."""
62
+ return {
63
+ "server": {"host": "127.0.0.1", "port": port},
64
+ "ssl": {
65
+ "enabled": True,
66
+ "cert_file": "./certs/server_cert.pem",
67
+ "key_file": "./certs/server_key.pem",
68
+ "ca_cert": "./certs/ca_cert.pem",
69
+ "verify_client": True
70
+ },
71
+ "security": {
72
+ "enabled": True,
73
+ "auth": {"enabled": True, "methods": ["certificate"]},
74
+ "permissions": {"enabled": False}
75
+ },
76
+ "protocols": {"enabled": True, "allowed_protocols": ["https", "mtls"]}
77
+ }
78
+ def generate_mtls_with_roles_config(port: int = 8005) -> Dict[str, Any]:
79
+ """Generate mTLS configuration with roles."""
80
+ return {
81
+ "server": {"host": "127.0.0.1", "port": port},
82
+ "ssl": {
83
+ "enabled": True,
84
+ "cert_file": "./certs/server_cert.pem",
85
+ "key_file": "./certs/server_key.pem",
86
+ "ca_cert": "./certs/ca_cert.pem",
87
+ "verify_client": True
88
+ },
89
+ "security": {
90
+ "enabled": True,
91
+ "auth": {"enabled": True, "methods": ["certificate"]},
92
+ "permissions": {"enabled": True, "roles_file": "./roles.json"}
93
+ },
94
+ "protocols": {"enabled": True, "allowed_protocols": ["https", "mtls"]}
95
+ }
96
+ def generate_roles_config() -> Dict[str, Any]:
97
+ """Generate roles configuration for testing."""
98
+ return {
99
+ "admin": {
100
+ "description": "Administrator role with full access",
101
+ "permissions": [
102
+ "read",
103
+ "write",
104
+ "execute",
105
+ "delete",
106
+ "admin",
107
+ "register",
108
+ "unregister",
109
+ "heartbeat",
110
+ "discover"
111
+ ],
112
+ "tokens": []
113
+ },
114
+ "user": {
115
+ "description": "User role with limited access",
116
+ "permissions": [
117
+ "read",
118
+ "execute",
119
+ "register",
120
+ "unregister",
121
+ "heartbeat",
122
+ "discover"
123
+ ],
124
+ "tokens": []
125
+ },
126
+ "readonly": {
127
+ "description": "Read-only role",
128
+ "permissions": [
129
+ "read",
130
+ "discover"
131
+ ],
132
+ "tokens": []
133
+ },
134
+ "guest": {
135
+ "description": "Guest role with read-only access",
136
+ "permissions": [
137
+ "read",
138
+ "discover"
139
+ ],
140
+ "tokens": []
141
+ },
142
+ "proxy": {
143
+ "description": "Proxy role for registration",
144
+ "permissions": [
145
+ "register",
146
+ "unregister",
147
+ "heartbeat",
148
+ "discover"
149
+ ],
150
+ "tokens": []
151
+ }
152
+ }
153
+ def generate_all_configs(output_dir: str) -> None:
154
+ """Generate all 6 configuration types and save them to files."""
155
+ configs = {
156
+ "http_simple": generate_http_simple_config(8000),
157
+ "http_token": generate_http_token_config(8001),
158
+ "https_simple": generate_https_simple_config(8002),
159
+ "https_token": generate_https_token_config(8003),
160
+ "mtls_no_roles": generate_mtls_no_roles_config(8004),
161
+ "mtls_with_roles": generate_mtls_with_roles_config(8005)
162
+ }
163
+ # Ensure output directory exists
164
+ os.makedirs(output_dir, exist_ok=True)
165
+ # Generate each configuration
166
+ for name, config in configs.items():
167
+ filename = os.path.join(output_dir, f"{name}.json")
168
+ with open(filename, 'w', encoding='utf-8') as f:
169
+ json.dump(config, f, indent=2, ensure_ascii=False)
170
+ print(f"Generated: {filename}")
171
+ # Generate roles configuration
172
+ roles_config = generate_roles_config()
173
+ roles_filename = os.path.join(output_dir, "roles.json")
174
+ with open(roles_filename, 'w', encoding='utf-8') as f:
175
+ json.dump(roles_config, f, indent=2, ensure_ascii=False)
176
+ print(f"Generated: {roles_filename}")
177
+ # Also create roles.json in certs directory for compatibility
178
+ certs_dir = os.path.join(os.path.dirname(output_dir), "certs")
179
+ if os.path.exists(certs_dir):
180
+ certs_roles_filename = os.path.join(certs_dir, "roles.json")
181
+ with open(certs_roles_filename, 'w', encoding='utf-8') as f:
182
+ json.dump(roles_config, f, indent=2, ensure_ascii=False)
183
+ print(f"Generated: {certs_roles_filename}")
184
+ print(f"\nGenerated {len(configs)} configuration files and roles.json in {output_dir}")
185
+ def main():
186
+ """Main function for command line execution."""
187
+ parser = argparse.ArgumentParser(
188
+ description="Generate test configurations for MCP Proxy Adapter"
189
+ )
190
+ parser.add_argument(
191
+ "--output-dir",
192
+ default="./configs",
193
+ help="Output directory for configuration files (default: ./configs)"
194
+ )
195
+ args = parser.parse_args()
196
+ try:
197
+ generate_all_configs(args.output_dir)
198
+ print("Configuration generation completed successfully!")
199
+ except Exception as e:
200
+ print(f"Error generating configurations: {e}")
201
+ return 1
202
+ return 0
203
+ if __name__ == "__main__":
204
+ exit(main())