mcp-proxy-adapter 6.3.4__py3-none-any.whl → 6.3.6__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 (131) hide show
  1. mcp_proxy_adapter/__init__.py +9 -5
  2. mcp_proxy_adapter/__main__.py +1 -1
  3. mcp_proxy_adapter/api/app.py +227 -176
  4. mcp_proxy_adapter/api/handlers.py +68 -60
  5. mcp_proxy_adapter/api/middleware/__init__.py +7 -5
  6. mcp_proxy_adapter/api/middleware/base.py +19 -16
  7. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +44 -34
  8. mcp_proxy_adapter/api/middleware/error_handling.py +57 -67
  9. mcp_proxy_adapter/api/middleware/factory.py +50 -52
  10. mcp_proxy_adapter/api/middleware/logging.py +46 -30
  11. mcp_proxy_adapter/api/middleware/performance.py +19 -16
  12. mcp_proxy_adapter/api/middleware/protocol_middleware.py +80 -50
  13. mcp_proxy_adapter/api/middleware/transport_middleware.py +26 -24
  14. mcp_proxy_adapter/api/middleware/unified_security.py +70 -51
  15. mcp_proxy_adapter/api/middleware/user_info_middleware.py +43 -34
  16. mcp_proxy_adapter/api/schemas.py +69 -43
  17. mcp_proxy_adapter/api/tool_integration.py +83 -63
  18. mcp_proxy_adapter/api/tools.py +60 -50
  19. mcp_proxy_adapter/commands/__init__.py +15 -6
  20. mcp_proxy_adapter/commands/auth_validation_command.py +107 -110
  21. mcp_proxy_adapter/commands/base.py +108 -112
  22. mcp_proxy_adapter/commands/builtin_commands.py +28 -18
  23. mcp_proxy_adapter/commands/catalog_manager.py +394 -265
  24. mcp_proxy_adapter/commands/cert_monitor_command.py +222 -204
  25. mcp_proxy_adapter/commands/certificate_management_command.py +210 -213
  26. mcp_proxy_adapter/commands/command_registry.py +275 -226
  27. mcp_proxy_adapter/commands/config_command.py +48 -33
  28. mcp_proxy_adapter/commands/dependency_container.py +22 -23
  29. mcp_proxy_adapter/commands/dependency_manager.py +65 -56
  30. mcp_proxy_adapter/commands/echo_command.py +15 -15
  31. mcp_proxy_adapter/commands/health_command.py +31 -29
  32. mcp_proxy_adapter/commands/help_command.py +97 -61
  33. mcp_proxy_adapter/commands/hooks.py +65 -49
  34. mcp_proxy_adapter/commands/key_management_command.py +148 -147
  35. mcp_proxy_adapter/commands/load_command.py +58 -40
  36. mcp_proxy_adapter/commands/plugins_command.py +80 -54
  37. mcp_proxy_adapter/commands/protocol_management_command.py +60 -48
  38. mcp_proxy_adapter/commands/proxy_registration_command.py +107 -115
  39. mcp_proxy_adapter/commands/reload_command.py +43 -37
  40. mcp_proxy_adapter/commands/result.py +26 -33
  41. mcp_proxy_adapter/commands/role_test_command.py +26 -26
  42. mcp_proxy_adapter/commands/roles_management_command.py +176 -173
  43. mcp_proxy_adapter/commands/security_command.py +134 -122
  44. mcp_proxy_adapter/commands/settings_command.py +47 -56
  45. mcp_proxy_adapter/commands/ssl_setup_command.py +109 -129
  46. mcp_proxy_adapter/commands/token_management_command.py +129 -158
  47. mcp_proxy_adapter/commands/transport_management_command.py +41 -36
  48. mcp_proxy_adapter/commands/unload_command.py +42 -37
  49. mcp_proxy_adapter/config.py +36 -35
  50. mcp_proxy_adapter/core/__init__.py +19 -21
  51. mcp_proxy_adapter/core/app_factory.py +30 -9
  52. mcp_proxy_adapter/core/app_runner.py +81 -64
  53. mcp_proxy_adapter/core/auth_validator.py +176 -182
  54. mcp_proxy_adapter/core/certificate_utils.py +469 -426
  55. mcp_proxy_adapter/core/client.py +155 -126
  56. mcp_proxy_adapter/core/client_manager.py +60 -54
  57. mcp_proxy_adapter/core/client_security.py +120 -91
  58. mcp_proxy_adapter/core/config_converter.py +176 -143
  59. mcp_proxy_adapter/core/config_validator.py +12 -4
  60. mcp_proxy_adapter/core/crl_utils.py +21 -7
  61. mcp_proxy_adapter/core/errors.py +64 -20
  62. mcp_proxy_adapter/core/logging.py +34 -29
  63. mcp_proxy_adapter/core/mtls_asgi.py +29 -25
  64. mcp_proxy_adapter/core/mtls_asgi_app.py +66 -54
  65. mcp_proxy_adapter/core/protocol_manager.py +154 -104
  66. mcp_proxy_adapter/core/proxy_client.py +202 -144
  67. mcp_proxy_adapter/core/proxy_registration.py +7 -3
  68. mcp_proxy_adapter/core/role_utils.py +139 -125
  69. mcp_proxy_adapter/core/security_adapter.py +88 -77
  70. mcp_proxy_adapter/core/security_factory.py +50 -44
  71. mcp_proxy_adapter/core/security_integration.py +72 -24
  72. mcp_proxy_adapter/core/server_adapter.py +68 -64
  73. mcp_proxy_adapter/core/server_engine.py +71 -53
  74. mcp_proxy_adapter/core/settings.py +68 -58
  75. mcp_proxy_adapter/core/ssl_utils.py +69 -56
  76. mcp_proxy_adapter/core/transport_manager.py +72 -60
  77. mcp_proxy_adapter/core/unified_config_adapter.py +201 -150
  78. mcp_proxy_adapter/core/utils.py +4 -2
  79. mcp_proxy_adapter/custom_openapi.py +107 -99
  80. mcp_proxy_adapter/examples/basic_framework/main.py +9 -2
  81. mcp_proxy_adapter/examples/commands/__init__.py +1 -1
  82. mcp_proxy_adapter/examples/create_certificates_simple.py +182 -71
  83. mcp_proxy_adapter/examples/debug_request_state.py +38 -19
  84. mcp_proxy_adapter/examples/debug_role_chain.py +53 -20
  85. mcp_proxy_adapter/examples/demo_client.py +48 -36
  86. mcp_proxy_adapter/examples/examples/basic_framework/main.py +9 -2
  87. mcp_proxy_adapter/examples/examples/full_application/__init__.py +1 -0
  88. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +22 -10
  89. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +24 -17
  90. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +16 -3
  91. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +13 -3
  92. mcp_proxy_adapter/examples/examples/full_application/main.py +27 -2
  93. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +48 -14
  94. mcp_proxy_adapter/examples/full_application/__init__.py +1 -0
  95. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +22 -10
  96. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +24 -17
  97. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +16 -3
  98. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +13 -3
  99. mcp_proxy_adapter/examples/full_application/main.py +27 -2
  100. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +48 -14
  101. mcp_proxy_adapter/examples/generate_all_certificates.py +198 -73
  102. mcp_proxy_adapter/examples/generate_certificates.py +31 -16
  103. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +220 -74
  104. mcp_proxy_adapter/examples/generate_test_configs.py +68 -91
  105. mcp_proxy_adapter/examples/proxy_registration_example.py +76 -75
  106. mcp_proxy_adapter/examples/run_example.py +23 -5
  107. mcp_proxy_adapter/examples/run_full_test_suite.py +109 -71
  108. mcp_proxy_adapter/examples/run_proxy_server.py +22 -9
  109. mcp_proxy_adapter/examples/run_security_tests.py +103 -41
  110. mcp_proxy_adapter/examples/run_security_tests_fixed.py +72 -36
  111. mcp_proxy_adapter/examples/scripts/config_generator.py +288 -187
  112. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +185 -72
  113. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +220 -74
  114. mcp_proxy_adapter/examples/security_test_client.py +196 -127
  115. mcp_proxy_adapter/examples/setup_test_environment.py +17 -29
  116. mcp_proxy_adapter/examples/test_config.py +19 -4
  117. mcp_proxy_adapter/examples/test_config_generator.py +23 -7
  118. mcp_proxy_adapter/examples/test_examples.py +84 -56
  119. mcp_proxy_adapter/examples/universal_client.py +119 -62
  120. mcp_proxy_adapter/openapi.py +108 -115
  121. mcp_proxy_adapter/utils/config_generator.py +429 -274
  122. mcp_proxy_adapter/version.py +1 -2
  123. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/METADATA +1 -1
  124. mcp_proxy_adapter-6.3.6.dist-info/RECORD +144 -0
  125. mcp_proxy_adapter-6.3.6.dist-info/top_level.txt +2 -0
  126. mcp_proxy_adapter_issue_package/demonstrate_issue.py +178 -0
  127. mcp_proxy_adapter-6.3.4.dist-info/RECORD +0 -143
  128. mcp_proxy_adapter-6.3.4.dist-info/top_level.txt +0 -1
  129. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/WHEEL +0 -0
  130. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/entry_points.txt +0 -0
  131. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/licenses/LICENSE +0 -0
@@ -15,8 +15,11 @@ import subprocess
15
15
  import sys
16
16
  from pathlib import Path
17
17
  from typing import Dict, List, Optional
18
+
19
+
18
20
  class CertificateGenerator:
19
21
  """Generate all certificates for security testing."""
22
+
20
23
  def __init__(self):
21
24
  self.project_root = Path(__file__).parent.parent.parent
22
25
  self.certs_dir = self.project_root / "mcp_proxy_adapter" / "examples" / "certs"
@@ -31,7 +34,7 @@ class CertificateGenerator:
31
34
  "country": "US",
32
35
  "state": "Test State",
33
36
  "city": "Test City",
34
- "validity_years": 10
37
+ "validity_years": 10,
35
38
  }
36
39
  self.server_config = {
37
40
  "common_name": "mcp-proxy-adapter-test.local",
@@ -40,7 +43,7 @@ class CertificateGenerator:
40
43
  "state": "Test State",
41
44
  "city": "Test City",
42
45
  "validity_years": 2,
43
- "san": ["localhost", "127.0.0.1", "mcp-proxy-adapter-test.local"]
46
+ "san": ["localhost", "127.0.0.1", "mcp-proxy-adapter-test.local"],
44
47
  }
45
48
  # Client certificates configuration
46
49
  self.client_certs = {
@@ -48,66 +51,63 @@ class CertificateGenerator:
48
51
  "common_name": "admin-client",
49
52
  "organization": "Test Organization",
50
53
  "roles": ["admin"],
51
- "permissions": ["*"]
54
+ "permissions": ["*"],
52
55
  },
53
56
  "user": {
54
57
  "common_name": "user-client",
55
58
  "organization": "Test Organization",
56
59
  "roles": ["user"],
57
- "permissions": ["read", "write"]
60
+ "permissions": ["read", "write"],
58
61
  },
59
62
  "readonly": {
60
63
  "common_name": "readonly-client",
61
64
  "organization": "Test Organization",
62
65
  "roles": ["readonly"],
63
- "permissions": ["read"]
66
+ "permissions": ["read"],
64
67
  },
65
68
  "guest": {
66
69
  "common_name": "guest-client",
67
70
  "organization": "Test Organization",
68
71
  "roles": ["guest"],
69
- "permissions": ["read"]
72
+ "permissions": ["read"],
70
73
  },
71
74
  "proxy": {
72
75
  "common_name": "proxy-client",
73
76
  "organization": "Test Organization",
74
77
  "roles": ["proxy"],
75
- "permissions": ["register", "discover"]
76
- }
78
+ "permissions": ["register", "discover"],
79
+ },
77
80
  }
78
81
  # Negative test certificates
79
82
  self.negative_certs = {
80
83
  "expired": {
81
84
  "common_name": "expired-client",
82
85
  "organization": "Test Organization",
83
- "validity_days": 1 # Will expire quickly
86
+ "validity_days": 1, # Will expire quickly
84
87
  },
85
88
  "wrong_org": {
86
89
  "common_name": "wrong-org-client",
87
90
  "organization": "Wrong Organization",
88
- "roles": ["user"]
91
+ "roles": ["user"],
89
92
  },
90
93
  "no_roles": {
91
94
  "common_name": "no-roles-client",
92
95
  "organization": "Test Organization",
93
- "roles": []
96
+ "roles": [],
94
97
  },
95
98
  "invalid_roles": {
96
99
  "common_name": "invalid-roles-client",
97
100
  "organization": "Test Organization",
98
- "roles": ["invalid_role"]
99
- }
101
+ "roles": ["invalid_role"],
102
+ },
100
103
  }
104
+
101
105
  def run_command(self, cmd: List[str], description: str) -> bool:
102
106
  """Run a command and handle errors."""
103
107
  try:
104
108
  print(f"šŸ”§ {description}...")
105
109
  result = subprocess.run(
106
- cmd,
107
- cwd=self.project_root,
108
- capture_output=True,
109
- text=True,
110
- check=True
110
+ cmd, cwd=self.project_root, capture_output=True, text=True, check=True
111
111
  )
112
112
  print(f"āœ… {description} completed successfully")
113
113
  return True
@@ -119,6 +119,7 @@ class CertificateGenerator:
119
119
  except Exception as e:
120
120
  print(f"āŒ {description} failed: {e}")
121
121
  return False
122
+
122
123
  def create_ca_certificate(self) -> bool:
123
124
  """Create Root CA certificate and key."""
124
125
  ca_cert_path = self.certs_dir / "ca_cert.pem"
@@ -127,24 +128,45 @@ class CertificateGenerator:
127
128
  print(f"ā„¹ļø CA certificate already exists: {ca_cert_path}")
128
129
  return True
129
130
  cmd = [
130
- sys.executable, "-m", "mcp_security_framework.cli.cert_cli", "create-ca",
131
- "-cn", self.ca_config["common_name"],
132
- "-o", self.ca_config["organization"],
133
- "-c", self.ca_config["country"],
134
- "-s", self.ca_config["state"],
135
- "-l", self.ca_config["city"],
136
- "-y", str(self.ca_config["validity_years"])
131
+ sys.executable,
132
+ "-m",
133
+ "mcp_security_framework.cli.cert_cli",
134
+ "create-ca",
135
+ "-cn",
136
+ self.ca_config["common_name"],
137
+ "-o",
138
+ self.ca_config["organization"],
139
+ "-c",
140
+ self.ca_config["country"],
141
+ "-s",
142
+ self.ca_config["state"],
143
+ "-l",
144
+ self.ca_config["city"],
145
+ "-y",
146
+ str(self.ca_config["validity_years"]),
137
147
  ]
138
148
  success = self.run_command(cmd, "Creating Root CA certificate")
139
149
  if success:
140
150
  # Move files to correct locations
141
- default_ca_cert = Path("./certs") / f"{self.ca_config['common_name'].lower().replace(' ', '_')}_ca.crt"
142
- default_ca_key = Path("./keys") / f"{self.ca_config['common_name'].lower().replace(' ', '_')}_ca.key"
151
+ default_ca_cert = (
152
+ Path("./certs")
153
+ / f"{self.ca_config['common_name'].lower().replace(' ', '_')}_ca.crt"
154
+ )
155
+ default_ca_key = (
156
+ Path("./keys")
157
+ / f"{self.ca_config['common_name'].lower().replace(' ', '_')}_ca.key"
158
+ )
143
159
  if default_ca_cert.exists():
144
- self.run_command(["mv", str(default_ca_cert), str(ca_cert_path)], "Moving CA certificate")
160
+ self.run_command(
161
+ ["mv", str(default_ca_cert), str(ca_cert_path)],
162
+ "Moving CA certificate",
163
+ )
145
164
  if default_ca_key.exists():
146
- self.run_command(["mv", str(default_ca_key), str(ca_key_path)], "Moving CA key")
165
+ self.run_command(
166
+ ["mv", str(default_ca_key), str(ca_key_path)], "Moving CA key"
167
+ )
147
168
  return success
169
+
148
170
  def create_server_certificate(self) -> bool:
149
171
  """Create server certificate for HTTPS and mTLS."""
150
172
  server_cert_path = self.certs_dir / "server_cert.pem"
@@ -154,13 +176,22 @@ class CertificateGenerator:
154
176
  return True
155
177
  # Create server certificate
156
178
  cmd = [
157
- sys.executable, "-m", "mcp_security_framework.cli.cert_cli", "create-server",
158
- "-cn", self.server_config["common_name"],
159
- "-o", self.server_config["organization"],
160
- "-c", self.server_config["country"],
161
- "-s", self.server_config["state"],
162
- "-l", self.server_config["city"],
163
- "-d", str(self.server_config["validity_years"] * 365) # Convert years to days
179
+ sys.executable,
180
+ "-m",
181
+ "mcp_security_framework.cli.cert_cli",
182
+ "create-server",
183
+ "-cn",
184
+ self.server_config["common_name"],
185
+ "-o",
186
+ self.server_config["organization"],
187
+ "-c",
188
+ self.server_config["country"],
189
+ "-s",
190
+ self.server_config["state"],
191
+ "-l",
192
+ self.server_config["city"],
193
+ "-d",
194
+ str(self.server_config["validity_years"] * 365), # Convert years to days
164
195
  ]
165
196
  # Add SAN if supported
166
197
  if self.server_config["san"]:
@@ -169,13 +200,26 @@ class CertificateGenerator:
169
200
  success = self.run_command(cmd, "Creating server certificate")
170
201
  if success:
171
202
  # Move files to correct locations
172
- default_server_cert = Path("./certs") / f"{self.server_config['common_name'].lower().replace('.', '_')}_server.crt"
173
- default_server_key = Path("./keys") / f"{self.server_config['common_name'].lower().replace('.', '_')}_server.key"
203
+ default_server_cert = (
204
+ Path("./certs")
205
+ / f"{self.server_config['common_name'].lower().replace('.', '_')}_server.crt"
206
+ )
207
+ default_server_key = (
208
+ Path("./keys")
209
+ / f"{self.server_config['common_name'].lower().replace('.', '_')}_server.key"
210
+ )
174
211
  if default_server_cert.exists():
175
- self.run_command(["mv", str(default_server_cert), str(server_cert_path)], "Moving server certificate")
212
+ self.run_command(
213
+ ["mv", str(default_server_cert), str(server_cert_path)],
214
+ "Moving server certificate",
215
+ )
176
216
  if default_server_key.exists():
177
- self.run_command(["mv", str(default_server_key), str(server_key_path)], "Moving server key")
217
+ self.run_command(
218
+ ["mv", str(default_server_key), str(server_key_path)],
219
+ "Moving server key",
220
+ )
178
221
  return success
222
+
179
223
  def create_client_certificate(self, name: str, config: Dict) -> bool:
180
224
  """Create client certificate with specific configuration."""
181
225
  cert_path = self.certs_dir / f"{name}_cert.pem"
@@ -184,13 +228,22 @@ class CertificateGenerator:
184
228
  print(f"ā„¹ļø Client certificate {name} already exists: {cert_path}")
185
229
  return True
186
230
  cmd = [
187
- sys.executable, "-m", "mcp_security_framework.cli.cert_cli", "create-client",
188
- "-cn", config["common_name"],
189
- "-o", config["organization"],
190
- "-c", self.ca_config["country"],
191
- "-s", self.ca_config["state"],
192
- "-l", self.ca_config["city"],
193
- "-d", "730" # 2 years in days
231
+ sys.executable,
232
+ "-m",
233
+ "mcp_security_framework.cli.cert_cli",
234
+ "create-client",
235
+ "-cn",
236
+ config["common_name"],
237
+ "-o",
238
+ config["organization"],
239
+ "-c",
240
+ self.ca_config["country"],
241
+ "-s",
242
+ self.ca_config["state"],
243
+ "-l",
244
+ self.ca_config["city"],
245
+ "-d",
246
+ "730", # 2 years in days
194
247
  ]
195
248
  # Add roles if specified
196
249
  if "roles" in config and config["roles"]:
@@ -206,13 +259,25 @@ class CertificateGenerator:
206
259
  success = self.run_command(cmd, f"Creating client certificate: {name}")
207
260
  if success:
208
261
  # Move files to correct locations
209
- default_client_cert = Path("./certs") / f"{config['common_name'].lower().replace('-', '_')}_client.crt"
210
- default_client_key = Path("./keys") / f"{config['common_name'].lower().replace('-', '_')}_client.key"
262
+ default_client_cert = (
263
+ Path("./certs")
264
+ / f"{config['common_name'].lower().replace('-', '_')}_client.crt"
265
+ )
266
+ default_client_key = (
267
+ Path("./keys")
268
+ / f"{config['common_name'].lower().replace('-', '_')}_client.key"
269
+ )
211
270
  if default_client_cert.exists():
212
- self.run_command(["mv", str(default_client_cert), str(cert_path)], f"Moving {name} certificate")
271
+ self.run_command(
272
+ ["mv", str(default_client_cert), str(cert_path)],
273
+ f"Moving {name} certificate",
274
+ )
213
275
  if default_client_key.exists():
214
- self.run_command(["mv", str(default_client_key), str(key_path)], f"Moving {name} key")
276
+ self.run_command(
277
+ ["mv", str(default_client_key), str(key_path)], f"Moving {name} key"
278
+ )
215
279
  return success
280
+
216
281
  def create_legacy_certificates(self) -> bool:
217
282
  """Create legacy certificate files for compatibility."""
218
283
  legacy_files = [
@@ -220,7 +285,7 @@ class CertificateGenerator:
220
285
  ("client_admin.crt", "client_admin.key"),
221
286
  ("admin.crt", "admin.key"),
222
287
  ("user.crt", "user.key"),
223
- ("readonly.crt", "readonly.key")
288
+ ("readonly.crt", "readonly.key"),
224
289
  ]
225
290
  success = True
226
291
  for cert_file, key_file in legacy_files:
@@ -228,22 +293,72 @@ class CertificateGenerator:
228
293
  key_path = self.certs_dir / key_file
229
294
  if not cert_path.exists() or not key_path.exists():
230
295
  # Copy from existing certificates
231
- if cert_file == "client.crt" and (self.certs_dir / "user_cert.pem").exists():
232
- self.run_command(["cp", str(self.certs_dir / "user_cert.pem"), str(cert_path)], f"Creating {cert_file}")
233
- self.run_command(["cp", str(self.certs_dir / "user_key.pem"), str(key_path)], f"Creating {key_file}")
234
- elif cert_file == "client_admin.crt" and (self.certs_dir / "admin_cert.pem").exists():
235
- self.run_command(["cp", str(self.certs_dir / "admin_cert.pem"), str(cert_path)], f"Creating {cert_file}")
236
- self.run_command(["cp", str(self.certs_dir / "admin_key.pem"), str(key_path)], f"Creating {key_file}")
237
- elif cert_file == "admin.crt" and (self.certs_dir / "admin_cert.pem").exists():
238
- self.run_command(["cp", str(self.certs_dir / "admin_cert.pem"), str(cert_path)], f"Creating {cert_file}")
239
- self.run_command(["cp", str(self.certs_dir / "admin_key.pem"), str(key_path)], f"Creating {key_file}")
240
- elif cert_file == "user.crt" and (self.certs_dir / "user_cert.pem").exists():
241
- self.run_command(["cp", str(self.certs_dir / "user_cert.pem"), str(cert_path)], f"Creating {cert_file}")
242
- self.run_command(["cp", str(self.certs_dir / "user_key.pem"), str(key_path)], f"Creating {key_file}")
243
- elif cert_file == "readonly.crt" and (self.certs_dir / "readonly_cert.pem").exists():
244
- self.run_command(["cp", str(self.certs_dir / "readonly_cert.pem"), str(cert_path)], f"Creating {cert_file}")
245
- self.run_command(["cp", str(self.certs_dir / "readonly_key.pem"), str(key_path)], f"Creating {key_file}")
296
+ if (
297
+ cert_file == "client.crt"
298
+ and (self.certs_dir / "user_cert.pem").exists()
299
+ ):
300
+ self.run_command(
301
+ ["cp", str(self.certs_dir / "user_cert.pem"), str(cert_path)],
302
+ f"Creating {cert_file}",
303
+ )
304
+ self.run_command(
305
+ ["cp", str(self.certs_dir / "user_key.pem"), str(key_path)],
306
+ f"Creating {key_file}",
307
+ )
308
+ elif (
309
+ cert_file == "client_admin.crt"
310
+ and (self.certs_dir / "admin_cert.pem").exists()
311
+ ):
312
+ self.run_command(
313
+ ["cp", str(self.certs_dir / "admin_cert.pem"), str(cert_path)],
314
+ f"Creating {cert_file}",
315
+ )
316
+ self.run_command(
317
+ ["cp", str(self.certs_dir / "admin_key.pem"), str(key_path)],
318
+ f"Creating {key_file}",
319
+ )
320
+ elif (
321
+ cert_file == "admin.crt"
322
+ and (self.certs_dir / "admin_cert.pem").exists()
323
+ ):
324
+ self.run_command(
325
+ ["cp", str(self.certs_dir / "admin_cert.pem"), str(cert_path)],
326
+ f"Creating {cert_file}",
327
+ )
328
+ self.run_command(
329
+ ["cp", str(self.certs_dir / "admin_key.pem"), str(key_path)],
330
+ f"Creating {key_file}",
331
+ )
332
+ elif (
333
+ cert_file == "user.crt"
334
+ and (self.certs_dir / "user_cert.pem").exists()
335
+ ):
336
+ self.run_command(
337
+ ["cp", str(self.certs_dir / "user_cert.pem"), str(cert_path)],
338
+ f"Creating {cert_file}",
339
+ )
340
+ self.run_command(
341
+ ["cp", str(self.certs_dir / "user_key.pem"), str(key_path)],
342
+ f"Creating {key_file}",
343
+ )
344
+ elif (
345
+ cert_file == "readonly.crt"
346
+ and (self.certs_dir / "readonly_cert.pem").exists()
347
+ ):
348
+ self.run_command(
349
+ [
350
+ "cp",
351
+ str(self.certs_dir / "readonly_cert.pem"),
352
+ str(cert_path),
353
+ ],
354
+ f"Creating {cert_file}",
355
+ )
356
+ self.run_command(
357
+ ["cp", str(self.certs_dir / "readonly_key.pem"), str(key_path)],
358
+ f"Creating {key_file}",
359
+ )
246
360
  return success
361
+
247
362
  def create_certificate_config(self) -> bool:
248
363
  """Create certificate configuration file."""
249
364
  config_path = self.certs_dir / "cert_config.json"
@@ -254,16 +369,17 @@ class CertificateGenerator:
254
369
  "key_storage_path": str(self.keys_dir),
255
370
  "default_validity_days": 365,
256
371
  "key_size": 2048,
257
- "hash_algorithm": "sha256"
372
+ "hash_algorithm": "sha256",
258
373
  }
259
374
  try:
260
- with open(config_path, 'w') as f:
375
+ with open(config_path, "w") as f:
261
376
  json.dump(config, f, indent=2)
262
377
  print(f"āœ… Created certificate config: {config_path}")
263
378
  return True
264
379
  except Exception as e:
265
380
  print(f"āŒ Failed to create certificate config: {e}")
266
381
  return False
382
+
267
383
  def validate_certificates(self) -> bool:
268
384
  """Validate all created certificates."""
269
385
  print("\nšŸ” Validating certificates...")
@@ -274,7 +390,7 @@ class CertificateGenerator:
274
390
  "user_cert.pem",
275
391
  "readonly_cert.pem",
276
392
  "guest_cert.pem",
277
- "proxy_cert.pem"
393
+ "proxy_cert.pem",
278
394
  ]
279
395
  success = True
280
396
  for cert_file in cert_files:
@@ -285,7 +401,7 @@ class CertificateGenerator:
285
401
  ["openssl", "x509", "-in", str(cert_path), "-text", "-noout"],
286
402
  capture_output=True,
287
403
  text=True,
288
- check=True
404
+ check=True,
289
405
  )
290
406
  print(f"āœ… {cert_file}: Valid")
291
407
  except subprocess.CalledProcessError:
@@ -294,6 +410,7 @@ class CertificateGenerator:
294
410
  else:
295
411
  print(f"āš ļø {cert_file}: Not found")
296
412
  return success
413
+
297
414
  def generate_all(self) -> bool:
298
415
  """Generate all certificates."""
299
416
  print("šŸ” Generating All Certificates for Security Testing")
@@ -336,16 +453,22 @@ class CertificateGenerator:
336
453
  print(f"šŸ“ Certificates directory: {self.certs_dir}")
337
454
  print(f"šŸ”‘ Keys directory: {self.keys_dir}")
338
455
  print("\nšŸ“‹ Generated certificates:")
339
- cert_files = list(self.certs_dir.glob("*.pem")) + list(self.certs_dir.glob("*.crt"))
456
+ cert_files = list(self.certs_dir.glob("*.pem")) + list(
457
+ self.certs_dir.glob("*.crt")
458
+ )
340
459
  for cert_file in sorted(cert_files):
341
460
  print(f" - {cert_file.name}")
342
- key_files = list(self.keys_dir.glob("*.pem")) + list(self.keys_dir.glob("*.key"))
461
+ key_files = list(self.keys_dir.glob("*.pem")) + list(
462
+ self.keys_dir.glob("*.key")
463
+ )
343
464
  for key_file in sorted(key_files):
344
465
  print(f" - {key_file.name}")
345
466
  else:
346
467
  print("āŒ Some certificates failed to generate")
347
468
  print("Check the error messages above")
348
469
  return success
470
+
471
+
349
472
  def main():
350
473
  """Main function."""
351
474
  generator = CertificateGenerator()
@@ -358,5 +481,7 @@ def main():
358
481
  except Exception as e:
359
482
  print(f"\nāŒ Certificate generation failed: {e}")
360
483
  sys.exit(1)
484
+
485
+
361
486
  if __name__ == "__main__":
362
487
  main()
@@ -11,6 +11,7 @@ import sys
11
11
  from pathlib import Path
12
12
  from datetime import datetime, timedelta, timezone
13
13
 
14
+
14
15
  def main():
15
16
  """Generate all certificates for examples."""
16
17
  print("šŸ” Certificate Generation Script")
@@ -26,8 +27,12 @@ def main():
26
27
  try:
27
28
  from mcp_security_framework.core.cert_manager import CertificateManager
28
29
  from mcp_security_framework.schemas import (
29
- CAConfig, ServerCertConfig, ClientCertConfig, CertificateConfig
30
+ CAConfig,
31
+ ServerCertConfig,
32
+ ClientCertConfig,
33
+ CertificateConfig,
30
34
  )
35
+
31
36
  print("āœ… mcp_security_framework API available")
32
37
  except ImportError as e:
33
38
  print(f"āŒ mcp_security_framework not found: {e}")
@@ -35,17 +40,17 @@ def main():
35
40
 
36
41
  try:
37
42
  print("šŸ”§ Creating root CA certificate...")
38
-
43
+
39
44
  # Initialize certificate manager first
40
45
  cert_config = CertificateConfig(
41
46
  cert_storage_path=str(cert_dir),
42
47
  key_storage_path=str(key_dir),
43
48
  default_validity_days=365,
44
49
  key_size=2048,
45
- hash_algorithm="sha256"
50
+ hash_algorithm="sha256",
46
51
  )
47
52
  cert_manager = CertificateManager(cert_config)
48
-
53
+
49
54
  # Create CA certificate using API
50
55
  ca_config = CAConfig(
51
56
  common_name="MCP Proxy Adapter CA",
@@ -56,14 +61,14 @@ def main():
56
61
  locality="City",
57
62
  validity_years=10,
58
63
  key_size=2048,
59
- hash_algorithm="sha256"
64
+ hash_algorithm="sha256",
60
65
  )
61
-
66
+
62
67
  ca_cert_pair = cert_manager.create_root_ca(ca_config)
63
68
  if not ca_cert_pair or not ca_cert_pair.certificate_path:
64
69
  print("āŒ Failed to create CA certificate")
65
70
  return False
66
-
71
+
67
72
  ca_cert_path = ca_cert_pair.certificate_path
68
73
  ca_key_path = ca_cert_pair.private_key_path
69
74
  print(f"āœ… Root CA certificate created: {ca_cert_path}")
@@ -78,7 +83,7 @@ def main():
78
83
  key_size=2048,
79
84
  subject_alt_names=["localhost", "127.0.0.1"],
80
85
  ca_cert_path=str(ca_cert_path),
81
- ca_key_path=str(ca_key_path)
86
+ ca_key_path=str(ca_key_path),
82
87
  )
83
88
 
84
89
  server_cert_pair = cert_manager.create_server_certificate(server_config)
@@ -95,11 +100,13 @@ def main():
95
100
  roles=["admin"],
96
101
  permissions=["read", "write", "delete"],
97
102
  ca_cert_path=str(ca_cert_path),
98
- ca_key_path=str(ca_key_path)
103
+ ca_key_path=str(ca_key_path),
99
104
  )
100
105
 
101
106
  admin_cert_pair = cert_manager.create_client_certificate(admin_config)
102
- print(f"āœ… Admin client certificate created: {admin_cert_pair.certificate_path}")
107
+ print(
108
+ f"āœ… Admin client certificate created: {admin_cert_pair.certificate_path}"
109
+ )
103
110
 
104
111
  print("šŸ”§ Creating user client certificate...")
105
112
  # Create user client certificate
@@ -112,7 +119,7 @@ def main():
112
119
  roles=["user"],
113
120
  permissions=["read", "write"],
114
121
  ca_cert_path=str(ca_cert_path),
115
- ca_key_path=str(ca_key_path)
122
+ ca_key_path=str(ca_key_path),
116
123
  )
117
124
 
118
125
  user_cert_pair = cert_manager.create_client_certificate(user_config)
@@ -129,28 +136,34 @@ def main():
129
136
  roles=["readonly"],
130
137
  permissions=["read"],
131
138
  ca_cert_path=str(ca_cert_path),
132
- ca_key_path=str(ca_key_path)
139
+ ca_key_path=str(ca_key_path),
133
140
  )
134
141
 
135
142
  readonly_cert_pair = cert_manager.create_client_certificate(readonly_config)
136
- print(f"āœ… Readonly client certificate created: {readonly_cert_pair.certificate_path}")
143
+ print(
144
+ f"āœ… Readonly client certificate created: {readonly_cert_pair.certificate_path}"
145
+ )
137
146
 
138
147
  print("\nšŸŽ‰ All certificates generated successfully!")
139
148
  print(f"šŸ“ Certificates are stored in the '{cert_dir}' directory")
140
149
  print(f"šŸ”‘ Private keys are stored in the '{key_dir}' directory")
141
150
  print(f"šŸ” CA certificate: {ca_cert_path}")
142
151
  print(f"šŸ” Server certificate: {server_cert_pair.certificate_path}")
143
-
152
+
144
153
  print("\n" + "=" * 60)
145
154
  print("āœ… CERTIFICATE GENERATION COMPLETED SUCCESSFULLY")
146
155
  print("=" * 60)
147
156
  print("\nšŸ“‹ NEXT STEPS:")
148
157
  print("1. Generate test configurations:")
149
- print(" python -m mcp_proxy_adapter.examples.generate_test_configs --output-dir configs")
158
+ print(
159
+ " python -m mcp_proxy_adapter.examples.generate_test_configs --output-dir configs"
160
+ )
150
161
  print("\n2. Run security tests:")
151
162
  print(" python -m mcp_proxy_adapter.examples.run_security_tests")
152
163
  print("\n3. Start basic framework example:")
153
- print(" python -m mcp_proxy_adapter.examples.basic_framework.main --config configs/https_simple.json")
164
+ print(
165
+ " python -m mcp_proxy_adapter.examples.basic_framework.main --config configs/https_simple.json"
166
+ )
154
167
  print("=" * 60)
155
168
  return True
156
169
 
@@ -158,6 +171,7 @@ def main():
158
171
  print(f"\nāŒ CERTIFICATE GENERATION FAILED: {e}")
159
172
  print("=" * 60)
160
173
  import traceback
174
+
161
175
  traceback.print_exc()
162
176
  print("\nšŸ”§ TROUBLESHOOTING:")
163
177
  print("1. Check if mcp_security_framework is installed:")
@@ -167,6 +181,7 @@ def main():
167
181
  print("=" * 60)
168
182
  return False
169
183
 
184
+
170
185
  if __name__ == "__main__":
171
186
  print("šŸ” Starting certificate generation...")
172
187
  success = main()