mcp-proxy-adapter 6.7.2__py3-none-any.whl → 6.8.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.
- mcp_proxy_adapter/api/app.py +30 -46
- mcp_proxy_adapter/core/app_factory.py +41 -55
- mcp_proxy_adapter/core/mtls_server.py +5 -1
- mcp_proxy_adapter/core/signal_handler.py +6 -4
- mcp_proxy_adapter/core/utils.py +142 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +10 -11
- mcp_proxy_adapter/examples/full_application/main.py +12 -62
- mcp_proxy_adapter/main.py +22 -0
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.7.2.dist-info → mcp_proxy_adapter-6.8.1.dist-info}/METADATA +1 -1
- {mcp_proxy_adapter-6.7.2.dist-info → mcp_proxy_adapter-6.8.1.dist-info}/RECORD +14 -16
- mcp_proxy_adapter/core/async_proxy_registration.py +0 -285
- mcp_proxy_adapter/examples/generate_certificates.py +0 -385
- {mcp_proxy_adapter-6.7.2.dist-info → mcp_proxy_adapter-6.8.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.7.2.dist-info → mcp_proxy_adapter-6.8.1.dist-info}/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.7.2.dist-info → mcp_proxy_adapter-6.8.1.dist-info}/top_level.txt +0 -0
@@ -1,385 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Generate Certificates Using mcp_security_framework with Bugfix
|
4
|
-
This script generates all necessary SSL certificates using the mcp_security_framework
|
5
|
-
with the CertificateConfig bugfix applied.
|
6
|
-
|
7
|
-
Author: Vasiliy Zdanovskiy
|
8
|
-
email: vasilyvz@gmail.com
|
9
|
-
"""
|
10
|
-
import json
|
11
|
-
import os
|
12
|
-
import sys
|
13
|
-
from pathlib import Path
|
14
|
-
from typing import Dict, List, Optional
|
15
|
-
|
16
|
-
# Import mcp_security_framework components
|
17
|
-
from mcp_security_framework.core.cert_manager import CertificateManager
|
18
|
-
from mcp_security_framework.schemas.config import CAConfig, ServerCertConfig, ClientCertConfig, CertificateConfig
|
19
|
-
from mcp_security_framework.utils.cert_utils import validate_certificate_format
|
20
|
-
|
21
|
-
# Import required certificates configuration
|
22
|
-
from required_certificates import REQUIRED_CERTIFICATES, get_all_required_certificates
|
23
|
-
|
24
|
-
|
25
|
-
class BugfixCertificateGenerator:
|
26
|
-
"""Certificate generator using mcp_security_framework with bugfix."""
|
27
|
-
|
28
|
-
def __init__(self):
|
29
|
-
"""Initialize the certificate generator."""
|
30
|
-
self.working_dir = Path.cwd()
|
31
|
-
self.certs_dir = self.working_dir / "certs"
|
32
|
-
self.keys_dir = self.working_dir / "keys"
|
33
|
-
|
34
|
-
# Ensure directories exist
|
35
|
-
self.certs_dir.mkdir(exist_ok=True)
|
36
|
-
self.keys_dir.mkdir(exist_ok=True)
|
37
|
-
|
38
|
-
# Certificate manager will be initialized after CA is created
|
39
|
-
self.cert_manager = None
|
40
|
-
|
41
|
-
def print_step(self, step: str, description: str):
|
42
|
-
"""Print a formatted step header."""
|
43
|
-
print(f"\n{'=' * 60}")
|
44
|
-
print(f"🔧 STEP {step}: {description}")
|
45
|
-
print(f"{'=' * 60}")
|
46
|
-
|
47
|
-
def print_success(self, message: str):
|
48
|
-
"""Print a success message."""
|
49
|
-
print(f"✅ {message}")
|
50
|
-
|
51
|
-
def print_error(self, message: str):
|
52
|
-
"""Print an error message."""
|
53
|
-
print(f"❌ {message}")
|
54
|
-
|
55
|
-
def print_info(self, message: str):
|
56
|
-
"""Print an info message."""
|
57
|
-
print(f"ℹ️ {message}")
|
58
|
-
|
59
|
-
def check_framework(self) -> bool:
|
60
|
-
"""Check if mcp_security_framework is available."""
|
61
|
-
try:
|
62
|
-
from mcp_security_framework import __version__
|
63
|
-
self.print_success(f"mcp_security_framework v{__version__} is available")
|
64
|
-
return True
|
65
|
-
except ImportError as e:
|
66
|
-
self.print_error(f"mcp_security_framework is not available: {e}")
|
67
|
-
return False
|
68
|
-
|
69
|
-
def _initialize_cert_manager(self, ca_creation_mode: bool = False):
|
70
|
-
"""Initialize certificate manager with configuration."""
|
71
|
-
cert_config = CertificateConfig(
|
72
|
-
enabled=True,
|
73
|
-
ca_creation_mode=ca_creation_mode,
|
74
|
-
ca_cert_path=str(self.certs_dir / "ca_cert.pem") if not ca_creation_mode else None,
|
75
|
-
ca_key_path=str(self.keys_dir / "ca_key.pem") if not ca_creation_mode else None,
|
76
|
-
cert_storage_path=str(self.certs_dir),
|
77
|
-
key_storage_path=str(self.keys_dir),
|
78
|
-
default_validity_days=365,
|
79
|
-
key_size=2048,
|
80
|
-
hash_algorithm="sha256"
|
81
|
-
)
|
82
|
-
self.cert_manager = CertificateManager(cert_config)
|
83
|
-
|
84
|
-
def generate_ca_certificate(self) -> bool:
|
85
|
-
"""Generate CA certificate using mcp_security_framework with bugfix."""
|
86
|
-
self.print_step("1", "Generating CA Certificate with Bugfix")
|
87
|
-
|
88
|
-
ca_info = REQUIRED_CERTIFICATES["ca_cert"]
|
89
|
-
|
90
|
-
try:
|
91
|
-
# Check if CA certificate already exists
|
92
|
-
if ca_info["output_cert"].exists() and ca_info["output_key"].exists():
|
93
|
-
self.print_info(f"CA certificate already exists: {ca_info['output_cert']}")
|
94
|
-
return True
|
95
|
-
|
96
|
-
# Create CA configuration
|
97
|
-
ca_config = CAConfig(
|
98
|
-
common_name=ca_info["common_name"],
|
99
|
-
organization=ca_info["organization"],
|
100
|
-
country=ca_info["country"],
|
101
|
-
state=ca_info["state"],
|
102
|
-
locality=ca_info["city"],
|
103
|
-
validity_years=ca_info["validity_days"] // 365,
|
104
|
-
key_size=2048,
|
105
|
-
hash_algorithm="sha256"
|
106
|
-
)
|
107
|
-
|
108
|
-
self.print_info(f"Generating CA certificate: {ca_info['common_name']}")
|
109
|
-
|
110
|
-
# Initialize certificate manager in CA creation mode
|
111
|
-
self._initialize_cert_manager(ca_creation_mode=True)
|
112
|
-
|
113
|
-
# Generate CA certificate using framework
|
114
|
-
result = self.cert_manager.create_root_ca(ca_config=ca_config)
|
115
|
-
|
116
|
-
if result:
|
117
|
-
# Save the generated certificate and key to expected locations
|
118
|
-
with open(ca_info["output_cert"], 'w') as f:
|
119
|
-
f.write(result.certificate_pem)
|
120
|
-
with open(ca_info["output_key"], 'w') as f:
|
121
|
-
f.write(result.private_key_pem)
|
122
|
-
|
123
|
-
self.print_success(f"CA certificate generated: {ca_info['output_cert']}")
|
124
|
-
# Reinitialize certificate manager in normal mode
|
125
|
-
self._initialize_cert_manager(ca_creation_mode=False)
|
126
|
-
return True
|
127
|
-
else:
|
128
|
-
self.print_error("Failed to generate CA certificate")
|
129
|
-
return False
|
130
|
-
|
131
|
-
except Exception as e:
|
132
|
-
self.print_error(f"Exception during CA certificate generation: {e}")
|
133
|
-
return False
|
134
|
-
|
135
|
-
def generate_server_certificate(self) -> bool:
|
136
|
-
"""Generate server certificate using mcp_security_framework."""
|
137
|
-
self.print_step("2", "Generating Server Certificate")
|
138
|
-
|
139
|
-
server_info = REQUIRED_CERTIFICATES["server_cert"]
|
140
|
-
|
141
|
-
try:
|
142
|
-
# Check if server certificate already exists
|
143
|
-
if server_info["output_cert"].exists() and server_info["output_key"].exists():
|
144
|
-
self.print_info(f"Server certificate already exists: {server_info['output_cert']}")
|
145
|
-
return True
|
146
|
-
|
147
|
-
# Ensure certificate manager is initialized in normal mode
|
148
|
-
if self.cert_manager is None:
|
149
|
-
self._initialize_cert_manager(ca_creation_mode=False)
|
150
|
-
|
151
|
-
# Create server certificate configuration
|
152
|
-
server_config = ServerCertConfig(
|
153
|
-
common_name=server_info["common_name"],
|
154
|
-
organization=server_info["organization"],
|
155
|
-
country=server_info["country"],
|
156
|
-
state=server_info["state"],
|
157
|
-
locality=server_info["city"],
|
158
|
-
validity_days=server_info["validity_days"],
|
159
|
-
key_size=2048,
|
160
|
-
hash_algorithm="sha256",
|
161
|
-
ca_cert_path=str(server_info["ca_cert_path"]),
|
162
|
-
ca_key_path=str(server_info["ca_key_path"]),
|
163
|
-
san=server_info.get("san", [])
|
164
|
-
)
|
165
|
-
|
166
|
-
self.print_info(f"Generating server certificate: {server_info['common_name']}")
|
167
|
-
|
168
|
-
# Generate server certificate using framework
|
169
|
-
result = self.cert_manager.create_server_certificate(server_config=server_config)
|
170
|
-
|
171
|
-
if result:
|
172
|
-
# Save the generated certificate and key to expected locations
|
173
|
-
with open(server_info["output_cert"], 'w') as f:
|
174
|
-
f.write(result.certificate_pem)
|
175
|
-
with open(server_info["output_key"], 'w') as f:
|
176
|
-
f.write(result.private_key_pem)
|
177
|
-
|
178
|
-
self.print_success(f"Server certificate generated: {server_info['output_cert']}")
|
179
|
-
return True
|
180
|
-
else:
|
181
|
-
self.print_error("Failed to generate server certificate")
|
182
|
-
return False
|
183
|
-
|
184
|
-
except Exception as e:
|
185
|
-
self.print_error(f"Exception during server certificate generation: {e}")
|
186
|
-
return False
|
187
|
-
|
188
|
-
def generate_client_certificate(self, cert_name: str) -> bool:
|
189
|
-
"""Generate client certificate using mcp_security_framework."""
|
190
|
-
self.print_step(f"3.{cert_name}", f"Generating {cert_name.title()} Client Certificate")
|
191
|
-
|
192
|
-
client_info = REQUIRED_CERTIFICATES[cert_name]
|
193
|
-
|
194
|
-
try:
|
195
|
-
# Check if client certificate already exists
|
196
|
-
if client_info["output_cert"].exists() and client_info["output_key"].exists():
|
197
|
-
self.print_info(f"{cert_name} certificate already exists: {client_info['output_cert']}")
|
198
|
-
return True
|
199
|
-
|
200
|
-
# Ensure certificate manager is initialized in normal mode
|
201
|
-
if self.cert_manager is None:
|
202
|
-
self._initialize_cert_manager(ca_creation_mode=False)
|
203
|
-
|
204
|
-
# Create client certificate configuration
|
205
|
-
client_config = ClientCertConfig(
|
206
|
-
common_name=client_info["common_name"],
|
207
|
-
organization=client_info["organization"],
|
208
|
-
country=client_info["country"],
|
209
|
-
state=client_info["state"],
|
210
|
-
locality=client_info["city"],
|
211
|
-
validity_days=client_info["validity_days"],
|
212
|
-
key_size=2048,
|
213
|
-
hash_algorithm="sha256",
|
214
|
-
ca_cert_path=str(client_info["ca_cert_path"]),
|
215
|
-
ca_key_path=str(client_info["ca_key_path"]),
|
216
|
-
roles=client_info.get("roles", []),
|
217
|
-
permissions=client_info.get("permissions", [])
|
218
|
-
)
|
219
|
-
|
220
|
-
self.print_info(f"Generating {cert_name} certificate: {client_info['common_name']}")
|
221
|
-
|
222
|
-
# Generate client certificate using framework
|
223
|
-
result = self.cert_manager.create_client_certificate(client_config=client_config)
|
224
|
-
|
225
|
-
if result:
|
226
|
-
# Save the generated certificate and key to expected locations
|
227
|
-
with open(client_info["output_cert"], 'w') as f:
|
228
|
-
f.write(result.certificate_pem)
|
229
|
-
with open(client_info["output_key"], 'w') as f:
|
230
|
-
f.write(result.private_key_pem)
|
231
|
-
|
232
|
-
# Also create a copy in certs/ directory for easier access
|
233
|
-
cert_name_base = client_info["common_name"].replace("-", "_")
|
234
|
-
certs_cert = self.certs_dir / f"{cert_name_base}_client.crt"
|
235
|
-
certs_key = self.certs_dir / f"{cert_name_base}_client.key"
|
236
|
-
|
237
|
-
with open(certs_cert, 'w') as f:
|
238
|
-
f.write(result.certificate_pem)
|
239
|
-
with open(certs_key, 'w') as f:
|
240
|
-
f.write(result.private_key_pem)
|
241
|
-
|
242
|
-
self.print_success(f"{cert_name} certificate generated: {client_info['output_cert']}")
|
243
|
-
self.print_success(f"Also created: {certs_cert} and {certs_key}")
|
244
|
-
return True
|
245
|
-
else:
|
246
|
-
self.print_error(f"Failed to generate {cert_name} certificate")
|
247
|
-
return False
|
248
|
-
|
249
|
-
except Exception as e:
|
250
|
-
self.print_error(f"Exception during {cert_name} certificate generation: {e}")
|
251
|
-
return False
|
252
|
-
|
253
|
-
def create_certificate_aliases(self) -> bool:
|
254
|
-
"""Create certificate aliases for different configurations."""
|
255
|
-
self.print_step("4", "Creating Certificate Aliases")
|
256
|
-
|
257
|
-
try:
|
258
|
-
# Create aliases for HTTPS configurations
|
259
|
-
if (self.certs_dir / "server_cert.pem").exists():
|
260
|
-
# HTTPS aliases
|
261
|
-
(self.certs_dir / "mcp_proxy_adapter_server.crt").unlink(missing_ok=True)
|
262
|
-
(self.certs_dir / "mcp_proxy_adapter_server.crt").symlink_to("server_cert.pem")
|
263
|
-
|
264
|
-
(self.certs_dir / "mcp_proxy_adapter_server.key").unlink(missing_ok=True)
|
265
|
-
(self.certs_dir / "mcp_proxy_adapter_server.key").symlink_to(self.keys_dir / "server_key.pem")
|
266
|
-
|
267
|
-
# mTLS aliases
|
268
|
-
(self.certs_dir / "localhost_server.crt").unlink(missing_ok=True)
|
269
|
-
(self.certs_dir / "localhost_server.crt").symlink_to("server_cert.pem")
|
270
|
-
|
271
|
-
self.print_success("Certificate aliases created")
|
272
|
-
|
273
|
-
# Create CA alias
|
274
|
-
if (self.certs_dir / "ca_cert.pem").exists():
|
275
|
-
(self.certs_dir / "mcp_proxy_adapter_ca_ca.crt").unlink(missing_ok=True)
|
276
|
-
(self.certs_dir / "mcp_proxy_adapter_ca_ca.crt").symlink_to("ca_cert.pem")
|
277
|
-
|
278
|
-
self.print_success("CA certificate alias created")
|
279
|
-
|
280
|
-
return True
|
281
|
-
|
282
|
-
except Exception as e:
|
283
|
-
self.print_error(f"Failed to create certificate aliases: {e}")
|
284
|
-
return False
|
285
|
-
|
286
|
-
def validate_certificates(self) -> bool:
|
287
|
-
"""Validate generated certificates using framework."""
|
288
|
-
self.print_step("5", "Validating Certificates")
|
289
|
-
|
290
|
-
all_required = get_all_required_certificates()
|
291
|
-
validation_results = []
|
292
|
-
|
293
|
-
for cert_name in all_required:
|
294
|
-
cert_info = REQUIRED_CERTIFICATES[cert_name]
|
295
|
-
cert_file = cert_info["output_cert"]
|
296
|
-
key_file = cert_info["output_key"]
|
297
|
-
|
298
|
-
if cert_file.exists() and key_file.exists():
|
299
|
-
try:
|
300
|
-
# Validate certificate format using framework
|
301
|
-
format_valid = validate_certificate_format(str(cert_file))
|
302
|
-
|
303
|
-
if format_valid:
|
304
|
-
self.print_success(f"{cert_name}: Valid format")
|
305
|
-
validation_results.append(True)
|
306
|
-
else:
|
307
|
-
self.print_error(f"{cert_name}: Invalid format")
|
308
|
-
validation_results.append(False)
|
309
|
-
|
310
|
-
except Exception as e:
|
311
|
-
self.print_error(f"{cert_name}: Validation failed - {e}")
|
312
|
-
validation_results.append(False)
|
313
|
-
else:
|
314
|
-
self.print_error(f"{cert_name}: Missing files")
|
315
|
-
validation_results.append(False)
|
316
|
-
|
317
|
-
success_count = sum(validation_results)
|
318
|
-
total_count = len(validation_results)
|
319
|
-
|
320
|
-
self.print_info(f"Validation results: {success_count}/{total_count} certificates valid")
|
321
|
-
|
322
|
-
return success_count == total_count
|
323
|
-
|
324
|
-
def generate_all_certificates(self) -> bool:
|
325
|
-
"""Generate all required certificates."""
|
326
|
-
print("🔐 Generating All Certificates Using mcp_security_framework with Bugfix")
|
327
|
-
print("=" * 60)
|
328
|
-
|
329
|
-
try:
|
330
|
-
# Check framework availability
|
331
|
-
if not self.check_framework():
|
332
|
-
return False
|
333
|
-
|
334
|
-
# Generate CA certificate first
|
335
|
-
if not self.generate_ca_certificate():
|
336
|
-
return False
|
337
|
-
|
338
|
-
# Generate server certificate
|
339
|
-
if not self.generate_server_certificate():
|
340
|
-
return False
|
341
|
-
|
342
|
-
# Generate client certificates
|
343
|
-
client_certs = ["admin_cert", "user_cert", "proxy_cert"]
|
344
|
-
for cert_name in client_certs:
|
345
|
-
if cert_name in REQUIRED_CERTIFICATES:
|
346
|
-
if not self.generate_client_certificate(cert_name):
|
347
|
-
return False
|
348
|
-
|
349
|
-
# Create aliases
|
350
|
-
if not self.create_certificate_aliases():
|
351
|
-
return False
|
352
|
-
|
353
|
-
# Validate certificates
|
354
|
-
if not self.validate_certificates():
|
355
|
-
return False
|
356
|
-
|
357
|
-
# Print summary
|
358
|
-
print(f"\n{'=' * 60}")
|
359
|
-
print("📊 CERTIFICATE GENERATION SUMMARY")
|
360
|
-
print(f"{'=' * 60}")
|
361
|
-
print("✅ All certificates generated successfully!")
|
362
|
-
print(f"📁 Certificates directory: {self.certs_dir}")
|
363
|
-
print(f"📁 Keys directory: {self.keys_dir}")
|
364
|
-
|
365
|
-
return True
|
366
|
-
|
367
|
-
except Exception as e:
|
368
|
-
self.print_error(f"Certificate generation failed: {e}")
|
369
|
-
return False
|
370
|
-
|
371
|
-
|
372
|
-
def main():
|
373
|
-
"""Main entry point."""
|
374
|
-
generator = BugfixCertificateGenerator()
|
375
|
-
|
376
|
-
try:
|
377
|
-
success = generator.generate_all_certificates()
|
378
|
-
sys.exit(0 if success else 1)
|
379
|
-
except Exception as e:
|
380
|
-
print(f"❌ Fatal error: {e}")
|
381
|
-
sys.exit(1)
|
382
|
-
|
383
|
-
|
384
|
-
if __name__ == "__main__":
|
385
|
-
main()
|
File without changes
|
File without changes
|
File without changes
|