mcp-proxy-adapter 6.9.6__py3-none-any.whl → 6.9.8__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/core/config_validator.py +130 -50
- mcp_proxy_adapter/examples/generate_config.py +3 -5
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.9.6.dist-info → mcp_proxy_adapter-6.9.8.dist-info}/METADATA +1 -1
- {mcp_proxy_adapter-6.9.6.dist-info → mcp_proxy_adapter-6.9.8.dist-info}/RECORD +8 -8
- {mcp_proxy_adapter-6.9.6.dist-info → mcp_proxy_adapter-6.9.8.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.9.6.dist-info → mcp_proxy_adapter-6.9.8.dist-info}/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.9.6.dist-info → mcp_proxy_adapter-6.9.8.dist-info}/top_level.txt +0 -0
@@ -46,7 +46,7 @@ class ConfigValidator:
|
|
46
46
|
def __init__(self, config_path: Optional[str] = None):
|
47
47
|
"""
|
48
48
|
Initialize configuration validator.
|
49
|
-
|
49
|
+
|
50
50
|
Args:
|
51
51
|
config_path: Path to configuration file for validation
|
52
52
|
"""
|
@@ -314,6 +314,11 @@ class ConfigValidator:
|
|
314
314
|
# Check conditional sections based on feature flags
|
315
315
|
for feature_name, feature_config in self.feature_flags.items():
|
316
316
|
enabled_key = feature_config["enabled_key"]
|
317
|
+
|
318
|
+
# Only check if the enabled key exists in the configuration
|
319
|
+
if not self._has_nested_key(enabled_key):
|
320
|
+
continue
|
321
|
+
|
317
322
|
is_enabled = self._get_nested_value_safe(enabled_key, False)
|
318
323
|
|
319
324
|
if is_enabled and feature_name in self.required_sections:
|
@@ -423,32 +428,35 @@ class ConfigValidator:
|
|
423
428
|
|
424
429
|
# Check SSL requirements
|
425
430
|
if requirements["ssl_enabled"]:
|
426
|
-
|
427
|
-
if
|
428
|
-
self.
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
431
|
+
# Only check SSL if ssl section exists
|
432
|
+
if self._has_nested_key("ssl.enabled"):
|
433
|
+
ssl_enabled = self._get_nested_value_safe("ssl.enabled", False)
|
434
|
+
if not ssl_enabled:
|
435
|
+
self.validation_results.append(ValidationResult(
|
436
|
+
level="error",
|
437
|
+
message=f"Protocol '{protocol}' requires SSL to be enabled",
|
438
|
+
section="ssl",
|
439
|
+
key="enabled"
|
433
440
|
))
|
434
441
|
|
435
442
|
# Check required SSL files
|
436
443
|
for file_key in requirements["required_files"]:
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
444
|
+
if self._has_nested_key(file_key):
|
445
|
+
file_path = self._get_nested_value(file_key)
|
446
|
+
if not file_path:
|
447
|
+
self.validation_results.append(ValidationResult(
|
448
|
+
level="error",
|
449
|
+
message=f"Protocol '{protocol}' requires {file_key} to be specified",
|
450
|
+
section="ssl",
|
451
|
+
key=file_key.split(".")[-1]
|
452
|
+
))
|
453
|
+
elif not os.path.exists(file_path):
|
454
|
+
self.validation_results.append(ValidationResult(
|
455
|
+
level="error",
|
456
|
+
message=f"Protocol '{protocol}' requires file '{file_path}' to exist",
|
457
|
+
section="ssl",
|
458
|
+
key=file_key.split(".")[-1]
|
459
|
+
))
|
452
460
|
|
453
461
|
# Check client verification requirements
|
454
462
|
if requirements["client_verification"]:
|
@@ -531,46 +539,110 @@ class ConfigValidator:
|
|
531
539
|
registration_enabled = self._get_nested_value_safe("proxy_registration.enabled", False)
|
532
540
|
|
533
541
|
if registration_enabled:
|
534
|
-
|
535
|
-
if not proxy_url:
|
542
|
+
if not self._has_nested_key("proxy_registration.proxy_url"):
|
536
543
|
self.validation_results.append(ValidationResult(
|
537
544
|
level="error",
|
538
545
|
message="Proxy registration is enabled but proxy_url is not specified",
|
539
546
|
section="proxy_registration",
|
540
547
|
key="proxy_url"
|
541
548
|
))
|
549
|
+
else:
|
550
|
+
proxy_url = self._get_nested_value("proxy_registration.proxy_url")
|
551
|
+
if not proxy_url:
|
552
|
+
self.validation_results.append(ValidationResult(
|
553
|
+
level="error",
|
554
|
+
message="Proxy registration is enabled but proxy_url is not specified",
|
555
|
+
section="proxy_registration",
|
556
|
+
key="proxy_url"
|
557
|
+
))
|
542
558
|
|
543
559
|
# Check authentication method consistency
|
544
560
|
auth_method = self._get_nested_value_safe("proxy_registration.auth_method", "none")
|
545
561
|
if auth_method != "none":
|
546
562
|
if auth_method == "certificate":
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
563
|
+
if not self._has_nested_key("proxy_registration.certificate.cert_file"):
|
564
|
+
self.validation_results.append(ValidationResult(
|
565
|
+
level="error",
|
566
|
+
message="Certificate authentication requires cert_file",
|
567
|
+
section="proxy_registration.certificate",
|
568
|
+
key="cert_file"
|
569
|
+
))
|
570
|
+
else:
|
571
|
+
cert_file = self._get_nested_value("proxy_registration.certificate.cert_file")
|
572
|
+
|
573
|
+
if not self._has_nested_key("proxy_registration.certificate.key_file"):
|
574
|
+
self.validation_results.append(ValidationResult(
|
575
|
+
level="error",
|
576
|
+
message="Certificate authentication requires key_file",
|
577
|
+
section="proxy_registration.certificate",
|
578
|
+
key="key_file"
|
579
|
+
))
|
580
|
+
else:
|
581
|
+
key_file = self._get_nested_value("proxy_registration.certificate.key_file")
|
582
|
+
|
583
|
+
if not cert_file or not key_file:
|
559
584
|
self.validation_results.append(ValidationResult(
|
560
585
|
level="error",
|
561
|
-
message="
|
586
|
+
message="Certificate authentication is enabled but certificate files are not specified",
|
562
587
|
section="proxy_registration",
|
588
|
+
key="certificate"
|
589
|
+
))
|
590
|
+
elif auth_method == "token":
|
591
|
+
if not self._has_nested_key("proxy_registration.token.token"):
|
592
|
+
self.validation_results.append(ValidationResult(
|
593
|
+
level="error",
|
594
|
+
message="Token authentication requires token",
|
595
|
+
section="proxy_registration.token",
|
563
596
|
key="token"
|
564
597
|
))
|
598
|
+
else:
|
599
|
+
token = self._get_nested_value("proxy_registration.token.token")
|
600
|
+
if not token:
|
601
|
+
self.validation_results.append(ValidationResult(
|
602
|
+
level="error",
|
603
|
+
message="Token authentication is enabled but token is not specified",
|
604
|
+
section="proxy_registration",
|
605
|
+
key="token"
|
606
|
+
))
|
565
607
|
|
566
608
|
def _validate_ssl_configuration(self) -> None:
|
567
609
|
"""Validate SSL configuration with detailed certificate validation."""
|
610
|
+
# Only validate SSL if the ssl section exists
|
611
|
+
if not self._has_nested_key("ssl.enabled"):
|
612
|
+
return
|
613
|
+
|
568
614
|
ssl_enabled = self._get_nested_value_safe("ssl.enabled", False)
|
569
615
|
|
570
616
|
if ssl_enabled:
|
571
|
-
|
572
|
-
|
573
|
-
|
617
|
+
if not self._has_nested_key("ssl.cert_file"):
|
618
|
+
self.validation_results.append(ValidationResult(
|
619
|
+
level="error",
|
620
|
+
message="SSL is enabled but cert_file is not specified",
|
621
|
+
section="ssl",
|
622
|
+
key="cert_file"
|
623
|
+
))
|
624
|
+
else:
|
625
|
+
cert_file = self._get_nested_value("ssl.cert_file")
|
626
|
+
|
627
|
+
if not self._has_nested_key("ssl.key_file"):
|
628
|
+
self.validation_results.append(ValidationResult(
|
629
|
+
level="error",
|
630
|
+
message="SSL is enabled but key_file is not specified",
|
631
|
+
section="ssl",
|
632
|
+
key="key_file"
|
633
|
+
))
|
634
|
+
else:
|
635
|
+
key_file = self._get_nested_value("ssl.key_file")
|
636
|
+
|
637
|
+
if not self._has_nested_key("ssl.ca_cert"):
|
638
|
+
self.validation_results.append(ValidationResult(
|
639
|
+
level="error",
|
640
|
+
message="SSL is enabled but ca_cert is not specified",
|
641
|
+
section="ssl",
|
642
|
+
key="ca_cert"
|
643
|
+
))
|
644
|
+
else:
|
645
|
+
ca_cert = self._get_nested_value("ssl.ca_cert")
|
574
646
|
|
575
647
|
# Check certificate file
|
576
648
|
if not cert_file:
|
@@ -632,21 +704,29 @@ class ConfigValidator:
|
|
632
704
|
roles_enabled = self._get_nested_value_safe("roles.enabled", False)
|
633
705
|
|
634
706
|
if roles_enabled:
|
635
|
-
|
636
|
-
if not config_file:
|
707
|
+
if not self._has_nested_key("roles.config_file"):
|
637
708
|
self.validation_results.append(ValidationResult(
|
638
709
|
level="error",
|
639
710
|
message="Roles are enabled but config_file is not specified",
|
640
711
|
section="roles",
|
641
712
|
key="config_file"
|
642
713
|
))
|
643
|
-
|
644
|
-
self.
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
714
|
+
else:
|
715
|
+
config_file = self._get_nested_value("roles.config_file")
|
716
|
+
if not config_file:
|
717
|
+
self.validation_results.append(ValidationResult(
|
718
|
+
level="error",
|
719
|
+
message="Roles are enabled but config_file is not specified",
|
720
|
+
section="roles",
|
721
|
+
key="config_file"
|
722
|
+
))
|
723
|
+
elif not os.path.exists(config_file):
|
724
|
+
self.validation_results.append(ValidationResult(
|
725
|
+
level="error",
|
726
|
+
message=f"Roles config file '{config_file}' does not exist",
|
727
|
+
section="roles",
|
728
|
+
key="config_file"
|
729
|
+
))
|
650
730
|
|
651
731
|
def _get_nested_value(self, key: str) -> Any:
|
652
732
|
"""Get value from nested dictionary using dot notation. Raises exception if key not found."""
|
@@ -16,7 +16,7 @@ from typing import Dict, Any, Optional
|
|
16
16
|
# Add the current directory to the path to import config_builder
|
17
17
|
sys.path.insert(0, str(Path(__file__).parent))
|
18
18
|
|
19
|
-
from config_builder import
|
19
|
+
from config_builder import generate_complete_config
|
20
20
|
|
21
21
|
# Import validation modules
|
22
22
|
try:
|
@@ -57,10 +57,8 @@ def create_config_from_flags(
|
|
57
57
|
Returns:
|
58
58
|
Configuration dictionary
|
59
59
|
"""
|
60
|
-
# Use the
|
61
|
-
|
62
|
-
|
63
|
-
return enhanced_create_config(protocol, token, roles, port, proxy_registration, proxy_url, auto_registration, server_id)
|
60
|
+
# Use the simple config builder
|
61
|
+
return generate_complete_config(host, port)
|
64
62
|
|
65
63
|
|
66
64
|
def save_config(config: Dict[str, Any], filename: str, output_dir: str, validate: bool = True) -> Path:
|
mcp_proxy_adapter/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-proxy-adapter
|
3
|
-
Version: 6.9.
|
3
|
+
Version: 6.9.8
|
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,7 +4,7 @@ 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=
|
7
|
+
mcp_proxy_adapter/version.py,sha256=Z-uhPZ5DfWcxa-jqj9qDbTk56I3mm3z8leUL7bJdNmM,74
|
8
8
|
mcp_proxy_adapter/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
9
|
mcp_proxy_adapter/api/app.py,sha256=PQ1Ch5ydJIHp3Z6gcMCzKkTsXPQAuZ9weHtQ-EXnNGY,37134
|
10
10
|
mcp_proxy_adapter/api/handlers.py,sha256=X-hcMNVeTAu4yVkKJEChEsj2bFptUS6sLNN-Wysjkow,10011
|
@@ -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=
|
65
|
+
mcp_proxy_adapter/core/config_validator.py,sha256=Pu9xh1PZ8fkI_SNAQmB1XecU-9kO4lokEJr9iUhOIRw,52677
|
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
|
@@ -95,7 +95,7 @@ mcp_proxy_adapter/examples/create_test_configs.py,sha256=9TrvLa4-bWLPu0SB1JXwWuC
|
|
95
95
|
mcp_proxy_adapter/examples/debug_request_state.py,sha256=Z3Gy2-fWtu7KIV9OkzGDLVz7TpL_h9V_99ica40uQBU,4489
|
96
96
|
mcp_proxy_adapter/examples/debug_role_chain.py,sha256=GLVXC2fJUwP8UJnXHchd1t-H53cjWLJI3RqTPrKmaak,8750
|
97
97
|
mcp_proxy_adapter/examples/demo_client.py,sha256=en2Rtb70B1sQmhL-vdQ4PDpKNNl_mfll2YCFT_jFCAg,10191
|
98
|
-
mcp_proxy_adapter/examples/generate_config.py,sha256=
|
98
|
+
mcp_proxy_adapter/examples/generate_config.py,sha256=h0_T9gi8ux6xf2nIF56VX1s2YBxLxQVIk3SbhmKsxEg,14977
|
99
99
|
mcp_proxy_adapter/examples/proxy_registration_example.py,sha256=vemRhftnjbiOBCJkmtDGqlWQ8syTG0a8755GCOnaQsg,12503
|
100
100
|
mcp_proxy_adapter/examples/required_certificates.py,sha256=YW9-V78oFiZ-FmHlGP-8FQFS569VdDVyq9hfvCv31pk,7133
|
101
101
|
mcp_proxy_adapter/examples/run_example.py,sha256=yp-a6HIrSk3ddQmbn0KkuKwErId0aNfj028TE6U-zmY,2626
|
@@ -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.
|
139
|
-
mcp_proxy_adapter-6.9.
|
140
|
-
mcp_proxy_adapter-6.9.
|
141
|
-
mcp_proxy_adapter-6.9.
|
142
|
-
mcp_proxy_adapter-6.9.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|