mcp-proxy-adapter 6.9.8__py3-none-any.whl → 6.9.11__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.
@@ -388,18 +388,19 @@ def create_app(
388
388
  try:
389
389
  from mcp_proxy_adapter.core.config_validator import ConfigValidator
390
390
 
391
- try:
392
- _validator = ConfigValidator()
393
- except TypeError:
394
- _validator = ConfigValidator(current_config)
395
- _validation = _validator.validate(current_config)
396
- if not _validation.is_valid:
391
+ _validator = ConfigValidator()
392
+ _validator.config_data = current_config
393
+ _validation_results = _validator.validate_config()
394
+ errors = [r for r in _validation_results if r.level == "error"]
395
+ warnings = [r for r in _validation_results if r.level == "warning"]
396
+
397
+ if errors:
397
398
  logger.critical("CRITICAL CONFIG ERROR: Invalid configuration at startup:")
398
- for _e in _validation.errors:
399
- logger.critical(f" - {_e}")
399
+ for _e in errors:
400
+ logger.critical(f" - {_e.message}")
400
401
  raise SystemExit(1)
401
- for _w in _validation.warnings:
402
- logger.warning(f"Config warning: {_w}")
402
+ for _w in warnings:
403
+ logger.warning(f"Config warning: {_w.message}")
403
404
  except Exception as _ex:
404
405
  logger.error(f"Failed to run startup configuration validation: {_ex}")
405
406
 
@@ -312,9 +312,15 @@ class ConfigValidator:
312
312
  ))
313
313
 
314
314
  # Check conditional sections based on feature flags
315
+ protocol = self._get_nested_value_safe("server.protocol", "http")
316
+
315
317
  for feature_name, feature_config in self.feature_flags.items():
316
318
  enabled_key = feature_config["enabled_key"]
317
319
 
320
+ # Skip SSL validation for HTTP protocol
321
+ if feature_name in ["ssl", "transport_ssl"] and protocol not in ["https", "mtls"]:
322
+ continue
323
+
318
324
  # Only check if the enabled key exists in the configuration
319
325
  if not self._has_nested_key(enabled_key):
320
326
  continue
@@ -365,9 +371,15 @@ class ConfigValidator:
365
371
 
366
372
  def _validate_feature_flags(self) -> None:
367
373
  """Validate feature flags and their dependencies."""
374
+ protocol = self._get_nested_value_safe("server.protocol", "http")
375
+
368
376
  for feature_name, feature_config in self.feature_flags.items():
369
377
  enabled_key = feature_config["enabled_key"]
370
378
 
379
+ # Skip SSL validation for HTTP protocol
380
+ if feature_name in ["ssl", "transport_ssl"] and protocol not in ["https", "mtls"]:
381
+ continue
382
+
371
383
  # Check if the enabled key exists in the configuration
372
384
  if not self._has_nested_key(enabled_key):
373
385
  # Skip validation if the feature flag key doesn't exist
@@ -415,6 +427,26 @@ class ConfigValidator:
415
427
  """Validate protocol-specific requirements."""
416
428
  protocol = self._get_nested_value_safe("server.protocol", "http")
417
429
 
430
+ # Check mTLS protocol requirements
431
+ if protocol == "mtls":
432
+ # mTLS requires HTTPS protocol
433
+ if not self._has_nested_key("ssl.enabled"):
434
+ self.validation_results.append(ValidationResult(
435
+ level="error",
436
+ message="mTLS protocol requires SSL configuration",
437
+ section="ssl",
438
+ key="enabled"
439
+ ))
440
+ else:
441
+ ssl_enabled = self._get_nested_value_safe("ssl.enabled", False)
442
+ if not ssl_enabled:
443
+ self.validation_results.append(ValidationResult(
444
+ level="error",
445
+ message="mTLS protocol requires SSL to be enabled",
446
+ section="ssl",
447
+ key="enabled"
448
+ ))
449
+
418
450
  if protocol not in self.protocol_requirements:
419
451
  self.validation_results.append(ValidationResult(
420
452
  level="error",
@@ -471,23 +503,37 @@ class ConfigValidator:
471
503
 
472
504
  def _validate_file_existence(self) -> None:
473
505
  """Validate that all referenced files exist."""
506
+ protocol = self._get_nested_value_safe("server.protocol", "http")
507
+
474
508
  file_keys = [
475
509
  "logging.log_dir",
476
510
  "commands.commands_directory",
477
511
  "commands.catalog_directory",
478
512
  "commands.custom_commands_path",
479
513
  "security.roles_file",
480
- "roles.config_file",
481
- "ssl.cert_file",
482
- "ssl.key_file",
483
- "ssl.ca_cert",
484
- "transport.ssl.cert_file",
485
- "transport.ssl.key_file",
486
- "transport.ssl.ca_cert",
487
- "proxy_registration.certificate.cert_file",
488
- "proxy_registration.certificate.key_file"
514
+ "roles.config_file"
489
515
  ]
490
516
 
517
+ # Only add SSL-related files if protocol requires SSL
518
+ if protocol in ["https", "mtls"]:
519
+ file_keys.extend([
520
+ "ssl.cert_file",
521
+ "ssl.key_file",
522
+ "ssl.ca_cert",
523
+ "transport.ssl.cert_file",
524
+ "transport.ssl.key_file",
525
+ "transport.ssl.ca_cert"
526
+ ])
527
+
528
+ # Only add proxy registration files if proxy registration is enabled
529
+ if self._has_nested_key("proxy_registration.enabled"):
530
+ proxy_enabled = self._get_nested_value_safe("proxy_registration.enabled", False)
531
+ if proxy_enabled:
532
+ file_keys.extend([
533
+ "proxy_registration.certificate.cert_file",
534
+ "proxy_registration.certificate.key_file"
535
+ ])
536
+
491
537
  for file_key in file_keys:
492
538
  file_path = self._get_nested_value(file_key)
493
539
  if file_path and not os.path.exists(file_path):
@@ -607,6 +653,11 @@ class ConfigValidator:
607
653
 
608
654
  def _validate_ssl_configuration(self) -> None:
609
655
  """Validate SSL configuration with detailed certificate validation."""
656
+ # Only validate SSL if the protocol requires it
657
+ protocol = self._get_nested_value_safe("server.protocol", "http")
658
+ if protocol not in ["https", "mtls"]:
659
+ return
660
+
610
661
  # Only validate SSL if the ssl section exists
611
662
  if not self._has_nested_key("ssl.enabled"):
612
663
  return
@@ -800,7 +851,7 @@ class ConfigValidator:
800
851
 
801
852
  # Check certificate expiration
802
853
  now = datetime.now(timezone.utc)
803
- not_after = cert.not_valid_after.replace(tzinfo=timezone.utc)
854
+ not_after = cert.not_valid_after_utc
804
855
 
805
856
  if now > not_after:
806
857
  self.validation_results.append(ValidationResult(
@@ -1062,7 +1113,7 @@ class ConfigValidator:
1062
1113
  level="error",
1063
1114
  message=f"Error validating certificate-key pair: {e}",
1064
1115
  section=section,
1065
- key=key
1116
+ key="cert_file"
1066
1117
  ))
1067
1118
 
1068
1119
  def _validate_certificate_chain(self, cert_file: str, ca_cert_file: str, section: str) -> None:
@@ -82,6 +82,12 @@ def generate_complete_config(host: str = "0.0.0.0", port: int = 8000) -> Dict[st
82
82
  "enabled": False,
83
83
  "level": "WARNING"
84
84
  },
85
+ "ssl": {
86
+ "enabled": False,
87
+ "cert_file": None,
88
+ "key_file": None,
89
+ "ca_cert": None
90
+ },
85
91
  "security": {
86
92
  "enabled": False,
87
93
  "tokens": {},
@@ -2,4 +2,4 @@
2
2
  Version information for MCP Proxy Adapter.
3
3
  """
4
4
 
5
- __version__ = "6.9.8"
5
+ __version__ = "6.9.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-proxy-adapter
3
- Version: 6.9.8
3
+ Version: 6.9.11
4
4
  Summary: Powerful JSON-RPC microservices framework with built-in security, authentication, and proxy registration
5
5
  Home-page: https://github.com/maverikod/mcp-proxy-adapter
6
6
  Author: Vasiliy Zdanovskiy
@@ -4,9 +4,9 @@ mcp_proxy_adapter/config.py,sha256=1Ngxri2IPGoytYdCF5pXzbLUXsWcf6qYENkaDkAppg0,2
4
4
  mcp_proxy_adapter/custom_openapi.py,sha256=XRviX-C-ZkSKdBhORhDTdeN_1FWyEfXZADiASft3t9I,28149
5
5
  mcp_proxy_adapter/main.py,sha256=NFcSW7WaEnimRWe5zj28D0CH9otHlRZ92d2Um6XiGjE,10399
6
6
  mcp_proxy_adapter/openapi.py,sha256=2UZOI09ZDRJuBYBjKbMyb2U4uASszoCMD5o_4ktRpvg,13480
7
- mcp_proxy_adapter/version.py,sha256=Z-uhPZ5DfWcxa-jqj9qDbTk56I3mm3z8leUL7bJdNmM,74
7
+ mcp_proxy_adapter/version.py,sha256=Wf-SxC1SZTUNwNpQ8kiOi8cpyG0lkn-RnVMho_BiR7w,75
8
8
  mcp_proxy_adapter/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- mcp_proxy_adapter/api/app.py,sha256=PQ1Ch5ydJIHp3Z6gcMCzKkTsXPQAuZ9weHtQ-EXnNGY,37134
9
+ mcp_proxy_adapter/api/app.py,sha256=La7xt02j4Zbg4sSc1iL72DM3UNFVddPlN4_xpaRauVo,37214
10
10
  mcp_proxy_adapter/api/handlers.py,sha256=X-hcMNVeTAu4yVkKJEChEsj2bFptUS6sLNN-Wysjkow,10011
11
11
  mcp_proxy_adapter/api/schemas.py,sha256=mevUvQnYgWQfkJAs3-vq3HalBzh6-Saa-Au1VVf0peE,12377
12
12
  mcp_proxy_adapter/api/tool_integration.py,sha256=AeUyvJVN-c3FrX5fHdagHL51saRH5d1ZKqc2YEx0rTE,10147
@@ -62,7 +62,7 @@ mcp_proxy_adapter/core/client.py,sha256=qIbPl8prEwK2U65kl-vGJW2_imo1E4i6HxG_VpPe
62
62
  mcp_proxy_adapter/core/client_manager.py,sha256=yD8HZJlOwmDbVU49YfzSbh1XZ-Vib8qfcLVAaH03Jdg,8832
63
63
  mcp_proxy_adapter/core/client_security.py,sha256=siUaYorcDbpZsEIKgLfg-jBKkp7z_Er8wsO63mDD3Is,13127
64
64
  mcp_proxy_adapter/core/config_converter.py,sha256=Wnnsrbw7DxtgDfLG-IyyzK-hkKu0_1yp7-7dW87tu_4,17422
65
- mcp_proxy_adapter/core/config_validator.py,sha256=Pu9xh1PZ8fkI_SNAQmB1XecU-9kO4lokEJr9iUhOIRw,52677
65
+ mcp_proxy_adapter/core/config_validator.py,sha256=B5Tu8nE_iSvB1jFJ6qseOZrUpd0QoK7phU9Sznv1HDI,54858
66
66
  mcp_proxy_adapter/core/crl_utils.py,sha256=Jnwq2UN52IoCDZCwByRP3XNMOJexftb-mVaH6zes6Fc,11706
67
67
  mcp_proxy_adapter/core/errors.py,sha256=CyhQgvMt0ooQjONa65XRBJ44y-l-E5_ES4KOuRvIpBk,8557
68
68
  mcp_proxy_adapter/core/logging.py,sha256=VIpiC6QTGLukRjiJoVpq3VEoLKhUeLNl8IdfljpW6ZU,9654
@@ -89,7 +89,7 @@ mcp_proxy_adapter/examples/__init__.py,sha256=k1F-EotAFbJ3JvK_rNgiH4bUztmxIWtYn0
89
89
  mcp_proxy_adapter/examples/bugfix_certificate_config.py,sha256=YGBE_SI6wYZUJLWl7-fP1OWXiSH4mHJAZHApgQWvG7s,10529
90
90
  mcp_proxy_adapter/examples/cert_manager_bugfix.py,sha256=UWUwItjqHqSnOMHocsz40_3deoZE8-vdROLW9y2fEns,7259
91
91
  mcp_proxy_adapter/examples/check_config.py,sha256=oDP3cymq76TqEpPztPihH-_sBktiEb2cG0MdVrY1Sj8,14104
92
- mcp_proxy_adapter/examples/config_builder.py,sha256=1Q84iq2JH6QTyHMUaykjTrdub6-P4jnMcLxfrVkbLSA,6831
92
+ mcp_proxy_adapter/examples/config_builder.py,sha256=z0I5d83kdNVaR1ATaeT_P4jmxBiIcovlNu7-9I6zgcQ,6978
93
93
  mcp_proxy_adapter/examples/config_cli.py,sha256=ZhVG6XEpTFe5-MzELByVsUh0AD4bHPBZeoXnGWbqifs,11059
94
94
  mcp_proxy_adapter/examples/create_test_configs.py,sha256=9TrvLa4-bWLPu0SB1JXwWuCsjj-4Vz3yAdowcHtCSSA,8228
95
95
  mcp_proxy_adapter/examples/debug_request_state.py,sha256=Z3Gy2-fWtu7KIV9OkzGDLVz7TpL_h9V_99ica40uQBU,4489
@@ -135,8 +135,8 @@ mcp_proxy_adapter/schemas/base_schema.json,sha256=v9G9cGMd4dRhCZsOQ_FMqOi5VFyVbI
135
135
  mcp_proxy_adapter/schemas/openapi_schema.json,sha256=C3yLkwmDsvnLW9B5gnKKdBGl4zxkeU-rEmjTrNVsQU0,8405
136
136
  mcp_proxy_adapter/schemas/roles.json,sha256=pgf_ZyqKyXbfGUxvobpiLiSJz9zzxrMuoVWEkEpz3N8,764
137
137
  mcp_proxy_adapter/schemas/roles_schema.json,sha256=deHgI7L6GwfBXacOlNtDgDJelDThppClC3Ti4Eh8rJY,5659
138
- mcp_proxy_adapter-6.9.8.dist-info/METADATA,sha256=309u-iZSLIck5tPqOQNJbrm2GI1BWBsZ6ZIRdwYz0ts,8510
139
- mcp_proxy_adapter-6.9.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
140
- mcp_proxy_adapter-6.9.8.dist-info/entry_points.txt,sha256=Bf-O5Aq80n22Ayu9fI9BgidzWqwzIVaqextAddTuHZw,563
141
- mcp_proxy_adapter-6.9.8.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
142
- mcp_proxy_adapter-6.9.8.dist-info/RECORD,,
138
+ mcp_proxy_adapter-6.9.11.dist-info/METADATA,sha256=x3eD4b9tIDjDfCFD04NRgBITZ9czwOMV2OEh8JTCW_s,8511
139
+ mcp_proxy_adapter-6.9.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
140
+ mcp_proxy_adapter-6.9.11.dist-info/entry_points.txt,sha256=Bf-O5Aq80n22Ayu9fI9BgidzWqwzIVaqextAddTuHZw,563
141
+ mcp_proxy_adapter-6.9.11.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
142
+ mcp_proxy_adapter-6.9.11.dist-info/RECORD,,