mcp-proxy-adapter 6.4.47__py3-none-any.whl → 6.6.0__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/handlers.py +58 -22
- mcp_proxy_adapter/api/middleware/unified_security.py +8 -12
- mcp_proxy_adapter/config.py +76 -117
- mcp_proxy_adapter/core/protocol_manager.py +25 -42
- mcp_proxy_adapter/core/security_integration.py +60 -97
- mcp_proxy_adapter/core/server_adapter.py +4 -0
- mcp_proxy_adapter/examples/config_builder.py +142 -428
- mcp_proxy_adapter/examples/config_builder_simple.py +271 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +186 -23
- mcp_proxy_adapter/examples/security_test_client.py +21 -7
- mcp_proxy_adapter/examples/test_config_builder.py +40 -0
- mcp_proxy_adapter/main.py +54 -27
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.4.47.dist-info → mcp_proxy_adapter-6.6.0.dist-info}/METADATA +1 -1
- {mcp_proxy_adapter-6.4.47.dist-info → mcp_proxy_adapter-6.6.0.dist-info}/RECORD +18 -17
- {mcp_proxy_adapter-6.4.47.dist-info → mcp_proxy_adapter-6.6.0.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.4.47.dist-info → mcp_proxy_adapter-6.6.0.dist-info}/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.4.47.dist-info → mcp_proxy_adapter-6.6.0.dist-info}/top_level.txt +0 -0
@@ -88,53 +88,42 @@ class SecurityIntegration:
|
|
88
88
|
# self.config is already the security section passed from unified_security.py
|
89
89
|
security_section = self.config
|
90
90
|
|
91
|
-
# Create SSL config
|
91
|
+
# Create SSL config - SSL is handled by server protocol, not security config
|
92
92
|
ssl_config = SSLConfig(
|
93
|
-
enabled=
|
94
|
-
cert_file=
|
95
|
-
key_file=
|
96
|
-
ca_cert_file=
|
97
|
-
client_cert_file=
|
98
|
-
client_key_file=
|
99
|
-
verify_mode=
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
),
|
105
|
-
check_hostname=security_section.get("ssl", {}).get("check_hostname", True),
|
106
|
-
check_expiry=security_section.get("ssl", {}).get("check_expiry", True),
|
107
|
-
expiry_warning_days=security_section.get("ssl", {}).get(
|
108
|
-
"expiry_warning_days", 30
|
109
|
-
),
|
93
|
+
enabled=False, # SSL is handled by server protocol
|
94
|
+
cert_file=None,
|
95
|
+
key_file=None,
|
96
|
+
ca_cert_file=None,
|
97
|
+
client_cert_file=None,
|
98
|
+
client_key_file=None,
|
99
|
+
verify_mode="CERT_REQUIRED",
|
100
|
+
min_tls_version="TLSv1.2",
|
101
|
+
check_hostname=True,
|
102
|
+
check_expiry=True,
|
103
|
+
expiry_warning_days=30,
|
110
104
|
)
|
111
105
|
|
112
|
-
# Create auth config
|
106
|
+
# Create auth config - use new simplified structure
|
113
107
|
auth_config = AuthConfig(
|
114
|
-
enabled=security_section.get("
|
115
|
-
methods=
|
116
|
-
api_keys=security_section.get("
|
117
|
-
user_roles=
|
118
|
-
jwt_secret=
|
119
|
-
jwt_algorithm=
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
"jwt_expiry_hours", 24
|
124
|
-
),
|
125
|
-
certificate_auth=security_section.get("auth", {}).get(
|
126
|
-
"certificate_auth", False
|
127
|
-
),
|
128
|
-
public_paths=security_section.get("auth", {}).get("public_paths", []),
|
108
|
+
enabled=security_section.get("enabled", True),
|
109
|
+
methods=["api_key"], # Use token-based authentication
|
110
|
+
api_keys=security_section.get("tokens", {}),
|
111
|
+
user_roles={}, # Will be handled by permissions
|
112
|
+
jwt_secret=None,
|
113
|
+
jwt_algorithm="HS256",
|
114
|
+
jwt_expiry_hours=24,
|
115
|
+
certificate_auth=False,
|
116
|
+
public_paths=[],
|
129
117
|
)
|
130
118
|
|
131
|
-
# Create permission config -
|
132
|
-
|
133
|
-
|
119
|
+
# Create permission config - use new simplified structure
|
120
|
+
roles = security_section.get("roles", {})
|
121
|
+
roles_file = security_section.get("roles_file")
|
122
|
+
|
123
|
+
# Enable permissions if we have roles or roles_file
|
124
|
+
permissions_enabled = bool(roles or roles_file)
|
134
125
|
|
135
126
|
if permissions_enabled:
|
136
|
-
roles_file = permissions_section.get("roles_file")
|
137
|
-
|
138
127
|
# If roles_file is None or empty string, don't pass it to avoid framework errors
|
139
128
|
if roles_file is None or roles_file == "":
|
140
129
|
logger.warning(
|
@@ -145,20 +134,14 @@ class SecurityIntegration:
|
|
145
134
|
permission_config = PermissionConfig(
|
146
135
|
enabled=True,
|
147
136
|
roles_file=roles_file,
|
148
|
-
default_role=
|
149
|
-
admin_role=
|
150
|
-
role_hierarchy=
|
151
|
-
permission_cache_enabled=
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
),
|
157
|
-
wildcard_permissions=permissions_section.get(
|
158
|
-
"wildcard_permissions", False
|
159
|
-
),
|
160
|
-
strict_mode=permissions_section.get("strict_mode", True),
|
161
|
-
roles=permissions_section.get("roles"),
|
137
|
+
default_role="guest",
|
138
|
+
admin_role="admin",
|
139
|
+
role_hierarchy={},
|
140
|
+
permission_cache_enabled=True,
|
141
|
+
permission_cache_ttl=300,
|
142
|
+
wildcard_permissions=False,
|
143
|
+
strict_mode=True,
|
144
|
+
roles=roles,
|
162
145
|
)
|
163
146
|
else:
|
164
147
|
# Create minimal permission config when permissions are disabled
|
@@ -175,57 +158,37 @@ class SecurityIntegration:
|
|
175
158
|
roles={},
|
176
159
|
)
|
177
160
|
|
178
|
-
# Create rate limit config
|
161
|
+
# Create rate limit config - use defaults since rate_limit section doesn't exist in new structure
|
179
162
|
rate_limit_config = RateLimitConfig(
|
180
|
-
enabled=
|
181
|
-
default_requests_per_minute=
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
window_size_seconds=security_section.get("rate_limit", {}).get(
|
189
|
-
"window_size_seconds", 60
|
190
|
-
),
|
191
|
-
storage_backend=security_section.get("rate_limit", {}).get(
|
192
|
-
"storage_backend", "memory"
|
193
|
-
),
|
194
|
-
exempt_paths=security_section.get("rate_limit", {}).get("exempt_paths", []),
|
195
|
-
exempt_roles=security_section.get("rate_limit", {}).get("exempt_roles", []),
|
163
|
+
enabled=True,
|
164
|
+
default_requests_per_minute=60,
|
165
|
+
default_requests_per_hour=1000,
|
166
|
+
burst_limit=2,
|
167
|
+
window_size_seconds=60,
|
168
|
+
storage_backend="memory",
|
169
|
+
exempt_paths=[],
|
170
|
+
exempt_roles=[],
|
196
171
|
)
|
197
172
|
|
198
|
-
# Create certificate config
|
173
|
+
# Create certificate config - certificates are handled by server protocol
|
199
174
|
certificate_config = CertificateConfig(
|
200
|
-
enabled=
|
201
|
-
ca_cert_path=
|
202
|
-
ca_key_path=
|
203
|
-
cert_storage_path=
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
),
|
209
|
-
default_validity_days=security_section.get("certificates", {}).get(
|
210
|
-
"default_validity_days", 365
|
211
|
-
),
|
212
|
-
key_size=security_section.get("certificates", {}).get("key_size", 2048),
|
213
|
-
hash_algorithm=security_section.get("certificates", {}).get(
|
214
|
-
"hash_algorithm", "sha256"
|
215
|
-
),
|
175
|
+
enabled=False, # Certificates are handled by server protocol
|
176
|
+
ca_cert_path=None,
|
177
|
+
ca_key_path=None,
|
178
|
+
cert_storage_path="./certs",
|
179
|
+
key_storage_path="./keys",
|
180
|
+
default_validity_days=365,
|
181
|
+
key_size=2048,
|
182
|
+
hash_algorithm="sha256",
|
216
183
|
)
|
217
184
|
|
218
|
-
# Create logging config
|
185
|
+
# Create logging config - use defaults since logging section doesn't exist in new structure
|
219
186
|
logging_config = LoggingConfig(
|
220
|
-
enabled=
|
221
|
-
level=
|
222
|
-
format=
|
223
|
-
|
224
|
-
|
225
|
-
console_output=security_section.get("logging", {}).get(
|
226
|
-
"console_output", True
|
227
|
-
),
|
228
|
-
file_path=security_section.get("logging", {}).get("file_path"),
|
187
|
+
enabled=True,
|
188
|
+
level="INFO",
|
189
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
190
|
+
console_output=True,
|
191
|
+
file_path=None,
|
229
192
|
)
|
230
193
|
|
231
194
|
# Create main security config
|
@@ -67,6 +67,10 @@ class ServerConfigAdapter:
|
|
67
67
|
if ssl_config.get("verify_client", False):
|
68
68
|
hypercorn_ssl["verify_mode"] = "CERT_REQUIRED"
|
69
69
|
|
70
|
+
# Map hostname checking
|
71
|
+
if "chk_hostname" in ssl_config:
|
72
|
+
hypercorn_ssl["check_hostname"] = ssl_config["chk_hostname"]
|
73
|
+
|
70
74
|
logger.debug(f"Converted SSL config to hypercorn: {hypercorn_ssl}")
|
71
75
|
return hypercorn_ssl
|
72
76
|
|