mcp-proxy-adapter 6.9.17__py3-none-any.whl → 6.9.18__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 +52 -52
- mcp_proxy_adapter/api/handlers.py +5 -5
- mcp_proxy_adapter/api/middleware/__init__.py +8 -8
- mcp_proxy_adapter/api/middleware/base.py +14 -14
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +7 -7
- mcp_proxy_adapter/api/middleware/error_handling.py +9 -9
- mcp_proxy_adapter/api/middleware/factory.py +17 -17
- mcp_proxy_adapter/api/middleware/logging.py +6 -6
- mcp_proxy_adapter/api/middleware/performance.py +3 -3
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +19 -19
- mcp_proxy_adapter/api/middleware/transport_middleware.py +3 -3
- mcp_proxy_adapter/api/middleware/unified_security.py +11 -11
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +21 -21
- mcp_proxy_adapter/api/tool_integration.py +3 -2
- mcp_proxy_adapter/api/tools.py +4 -3
- mcp_proxy_adapter/commands/auth_validation_command.py +6 -5
- mcp_proxy_adapter/commands/base.py +10 -10
- mcp_proxy_adapter/commands/builtin_commands.py +6 -6
- mcp_proxy_adapter/commands/catalog_manager.py +74 -74
- mcp_proxy_adapter/commands/cert_monitor_command.py +13 -12
- mcp_proxy_adapter/commands/certificate_management_command.py +20 -19
- mcp_proxy_adapter/commands/command_registry.py +68 -67
- mcp_proxy_adapter/commands/config_command.py +3 -1
- mcp_proxy_adapter/commands/dependency_manager.py +10 -10
- mcp_proxy_adapter/commands/help_command.py +21 -20
- mcp_proxy_adapter/commands/hooks.py +27 -27
- mcp_proxy_adapter/commands/key_management_command.py +19 -18
- mcp_proxy_adapter/commands/plugins_command.py +2 -1
- mcp_proxy_adapter/commands/protocol_management_command.py +6 -6
- mcp_proxy_adapter/commands/proxy_registration_command.py +9 -9
- mcp_proxy_adapter/commands/registration_status_command.py +4 -4
- mcp_proxy_adapter/commands/reload_command.py +5 -5
- mcp_proxy_adapter/commands/role_test_command.py +2 -1
- mcp_proxy_adapter/commands/roles_management_command.py +9 -8
- mcp_proxy_adapter/commands/security_command.py +3 -2
- mcp_proxy_adapter/commands/ssl_setup_command.py +7 -6
- mcp_proxy_adapter/commands/token_management_command.py +12 -11
- mcp_proxy_adapter/commands/transport_management_command.py +2 -2
- mcp_proxy_adapter/config.py +3 -3
- mcp_proxy_adapter/core/__init__.py +1 -1
- mcp_proxy_adapter/core/app_runner.py +3 -3
- mcp_proxy_adapter/core/auth_validator.py +9 -9
- mcp_proxy_adapter/core/certificate_utils.py +27 -27
- mcp_proxy_adapter/core/client_manager.py +13 -13
- mcp_proxy_adapter/core/client_security.py +26 -26
- mcp_proxy_adapter/core/config_converter.py +18 -18
- mcp_proxy_adapter/core/config_validator.py +5 -1
- mcp_proxy_adapter/core/crl_utils.py +22 -22
- mcp_proxy_adapter/core/logging.py +21 -13
- mcp_proxy_adapter/core/mtls_asgi.py +7 -7
- mcp_proxy_adapter/core/mtls_asgi_app.py +9 -9
- mcp_proxy_adapter/core/mtls_proxy.py +9 -9
- mcp_proxy_adapter/core/mtls_server.py +18 -18
- mcp_proxy_adapter/core/protocol_manager.py +29 -29
- mcp_proxy_adapter/core/proxy_registration.py +67 -67
- mcp_proxy_adapter/core/security_adapter.py +18 -18
- mcp_proxy_adapter/core/security_factory.py +16 -16
- mcp_proxy_adapter/core/security_integration.py +6 -6
- mcp_proxy_adapter/core/server_adapter.py +12 -12
- mcp_proxy_adapter/core/server_engine.py +17 -17
- mcp_proxy_adapter/core/signal_handler.py +12 -12
- mcp_proxy_adapter/core/ssl_utils.py +12 -12
- mcp_proxy_adapter/core/transport_manager.py +14 -14
- mcp_proxy_adapter/core/unified_config_adapter.py +6 -6
- mcp_proxy_adapter/core/utils.py +5 -5
- mcp_proxy_adapter/custom_openapi.py +7 -7
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +2 -2
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +6 -5
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +44 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +66 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +64 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +21 -21
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +6 -6
- mcp_proxy_adapter/examples/full_application/main.py +28 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +38 -38
- mcp_proxy_adapter/examples/test_framework_complete.py +35 -35
- mcp_proxy_adapter/examples/test_mcp_server.py +2 -2
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +386 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +248 -0
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.9.17.dist-info → mcp_proxy_adapter-6.9.18.dist-info}/METADATA +1 -1
- mcp_proxy_adapter-6.9.18.dist-info/RECORD +149 -0
- mcp_proxy_adapter-6.9.17.dist-info/RECORD +0 -144
- {mcp_proxy_adapter-6.9.17.dist-info → mcp_proxy_adapter-6.9.18.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.9.17.dist-info → mcp_proxy_adapter-6.9.18.dist-info}/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.9.17.dist-info → mcp_proxy_adapter-6.9.18.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,7 @@ from typing import Dict, Any, List, Optional, Type
|
|
10
10
|
|
11
11
|
from fastapi import FastAPI
|
12
12
|
|
13
|
-
from mcp_proxy_adapter.core.logging import
|
13
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
14
14
|
from mcp_proxy_adapter.core.security_factory import SecurityFactory
|
15
15
|
from .base import BaseMiddleware
|
16
16
|
from .unified_security import UnifiedSecurityMiddleware
|
@@ -39,7 +39,7 @@ class MiddlewareFactory:
|
|
39
39
|
self.config = config
|
40
40
|
self.middleware_stack: List[BaseMiddleware] = []
|
41
41
|
|
42
|
-
|
42
|
+
get_global_logger().info("Middleware factory initialized")
|
43
43
|
|
44
44
|
def create_security_middleware(self) -> Optional[UnifiedSecurityMiddleware]:
|
45
45
|
"""
|
@@ -52,17 +52,17 @@ class MiddlewareFactory:
|
|
52
52
|
security_config = self.config.get("security", {})
|
53
53
|
|
54
54
|
if not security_config.get("enabled", True):
|
55
|
-
|
55
|
+
get_global_logger().info("Security middleware disabled by configuration")
|
56
56
|
return None
|
57
57
|
|
58
58
|
middleware = UnifiedSecurityMiddleware(self.app, self.config)
|
59
59
|
self.middleware_stack.append(middleware)
|
60
60
|
|
61
|
-
|
61
|
+
get_global_logger().info("Unified security middleware created successfully")
|
62
62
|
return middleware
|
63
63
|
|
64
64
|
except Exception as e:
|
65
|
-
|
65
|
+
get_global_logger().error(f"Failed to create unified security middleware: {e}")
|
66
66
|
return None
|
67
67
|
|
68
68
|
def create_error_handling_middleware(self) -> Optional[ErrorHandlingMiddleware]:
|
@@ -79,11 +79,11 @@ class MiddlewareFactory:
|
|
79
79
|
middleware = ErrorHandlingMiddleware(self.app)
|
80
80
|
self.middleware_stack.append(middleware)
|
81
81
|
|
82
|
-
|
82
|
+
get_global_logger().info("Error handling middleware created successfully")
|
83
83
|
return middleware
|
84
84
|
|
85
85
|
except Exception as e:
|
86
|
-
|
86
|
+
get_global_logger().error(f"Failed to create error handling middleware: {e}")
|
87
87
|
return None
|
88
88
|
|
89
89
|
def create_logging_middleware(self) -> Optional[LoggingMiddleware]:
|
@@ -100,11 +100,11 @@ class MiddlewareFactory:
|
|
100
100
|
middleware = LoggingMiddleware(self.app, self.config)
|
101
101
|
self.middleware_stack.append(middleware)
|
102
102
|
|
103
|
-
|
103
|
+
get_global_logger().info("Logging middleware created successfully")
|
104
104
|
return middleware
|
105
105
|
|
106
106
|
except Exception as e:
|
107
|
-
|
107
|
+
get_global_logger().error(f"Failed to create logging middleware: {e}")
|
108
108
|
return None
|
109
109
|
|
110
110
|
def create_user_info_middleware(self) -> Optional[UserInfoMiddleware]:
|
@@ -118,11 +118,11 @@ class MiddlewareFactory:
|
|
118
118
|
middleware = UserInfoMiddleware(self.app, self.config)
|
119
119
|
self.middleware_stack.append(middleware)
|
120
120
|
|
121
|
-
|
121
|
+
get_global_logger().info("User info middleware created successfully")
|
122
122
|
return middleware
|
123
123
|
|
124
124
|
except Exception as e:
|
125
|
-
|
125
|
+
get_global_logger().error(f"Failed to create user info middleware: {e}")
|
126
126
|
return None
|
127
127
|
|
128
128
|
def create_all_middleware(self) -> List[BaseMiddleware]:
|
@@ -154,7 +154,7 @@ class MiddlewareFactory:
|
|
154
154
|
if user_info_middleware:
|
155
155
|
middleware_list.append(user_info_middleware)
|
156
156
|
|
157
|
-
|
157
|
+
get_global_logger().info(f"Created {len(middleware_list)} middleware components")
|
158
158
|
return middleware_list
|
159
159
|
|
160
160
|
def get_middleware_by_type(
|
@@ -195,7 +195,7 @@ class MiddlewareFactory:
|
|
195
195
|
|
196
196
|
# Validate security configuration
|
197
197
|
if not SecurityFactory.validate_config(self.config):
|
198
|
-
|
198
|
+
get_global_logger().error("Security configuration validation failed")
|
199
199
|
return False
|
200
200
|
|
201
201
|
# Validate middleware-specific configurations
|
@@ -203,19 +203,19 @@ class MiddlewareFactory:
|
|
203
203
|
# Check required fields for security middleware
|
204
204
|
auth_config = security_config.get("auth", {})
|
205
205
|
if not isinstance(auth_config, dict):
|
206
|
-
|
206
|
+
get_global_logger().error("Auth configuration must be a dictionary")
|
207
207
|
return False
|
208
208
|
|
209
209
|
ssl_config = security_config.get("ssl", {})
|
210
210
|
if not isinstance(ssl_config, dict):
|
211
|
-
|
211
|
+
get_global_logger().error("SSL configuration must be a dictionary")
|
212
212
|
return False
|
213
213
|
|
214
|
-
|
214
|
+
get_global_logger().info("Middleware configuration validation passed")
|
215
215
|
return True
|
216
216
|
|
217
217
|
except Exception as e:
|
218
|
-
|
218
|
+
get_global_logger().error(f"Middleware configuration validation failed: {e}")
|
219
219
|
return False
|
220
220
|
|
221
221
|
def get_middleware_info(self) -> Dict[str, Any]:
|
@@ -9,7 +9,7 @@ from typing import Callable, Awaitable, Dict, Any
|
|
9
9
|
|
10
10
|
from fastapi import Request, Response
|
11
11
|
|
12
|
-
from mcp_proxy_adapter.core.logging import
|
12
|
+
from mcp_proxy_adapter.core.logging import get_global_logger, RequestLogger
|
13
13
|
from .base import BaseMiddleware
|
14
14
|
|
15
15
|
|
@@ -42,14 +42,14 @@ class LoggingMiddleware(BaseMiddleware):
|
|
42
42
|
Returns:
|
43
43
|
Response.
|
44
44
|
"""
|
45
|
-
|
45
|
+
get_global_logger().debug(f"🔍 LoggingMiddleware.dispatch START - {request.method} {request.url.path}")
|
46
46
|
|
47
47
|
# Generate unique ID for request
|
48
48
|
request_id = str(uuid.uuid4())
|
49
49
|
request.state.request_id = request_id
|
50
|
-
|
50
|
+
get_global_logger().debug(f"🔍 LoggingMiddleware - Generated request ID: {request_id}")
|
51
51
|
|
52
|
-
# Create context
|
52
|
+
# Create context get_global_logger() for this request
|
53
53
|
req_logger = RequestLogger("mcp_proxy_adapter.api.middleware", request_id)
|
54
54
|
|
55
55
|
# Log request start
|
@@ -101,9 +101,9 @@ class LoggingMiddleware(BaseMiddleware):
|
|
101
101
|
|
102
102
|
# Call the next middleware or main handler
|
103
103
|
try:
|
104
|
-
|
104
|
+
get_global_logger().debug(f"🔍 LoggingMiddleware - About to call next handler")
|
105
105
|
response = await call_next(request)
|
106
|
-
|
106
|
+
get_global_logger().debug(f"🔍 LoggingMiddleware - Next handler completed with status: {response.status_code}")
|
107
107
|
|
108
108
|
# Log request completion
|
109
109
|
process_time = time.time() - start_time
|
@@ -8,7 +8,7 @@ from typing import Dict, List, Callable, Awaitable
|
|
8
8
|
|
9
9
|
from fastapi import Request, Response
|
10
10
|
|
11
|
-
from mcp_proxy_adapter.core.logging import
|
11
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
12
12
|
from .base import BaseMiddleware
|
13
13
|
|
14
14
|
|
@@ -69,7 +69,7 @@ class PerformanceMiddleware(BaseMiddleware):
|
|
69
69
|
"""
|
70
70
|
Logs performance statistics.
|
71
71
|
"""
|
72
|
-
|
72
|
+
get_global_logger().info("Performance statistics:")
|
73
73
|
|
74
74
|
for path, times in self.request_times.items():
|
75
75
|
if len(times) > 1:
|
@@ -79,7 +79,7 @@ class PerformanceMiddleware(BaseMiddleware):
|
|
79
79
|
# Calculate 95th percentile
|
80
80
|
p95_time = sorted(times)[int(len(times) * 0.95)]
|
81
81
|
|
82
|
-
|
82
|
+
get_global_logger().info(
|
83
83
|
f"Path: {path}, Requests: {len(times)}, "
|
84
84
|
f"Avg: {avg_time:.3f}s, Min: {min_time:.3f}s, "
|
85
85
|
f"Max: {max_time:.3f}s, p95: {p95_time:.3f}s"
|
@@ -10,7 +10,7 @@ from starlette.middleware.base import BaseHTTPMiddleware
|
|
10
10
|
from starlette.responses import JSONResponse
|
11
11
|
|
12
12
|
from mcp_proxy_adapter.core.protocol_manager import get_protocol_manager
|
13
|
-
from mcp_proxy_adapter.core.logging import
|
13
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
14
14
|
|
15
15
|
|
16
16
|
class ProtocolMiddleware(BaseHTTPMiddleware):
|
@@ -38,27 +38,27 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
38
38
|
try:
|
39
39
|
normalized_config = app_config.get_all()
|
40
40
|
except Exception as e:
|
41
|
-
|
41
|
+
get_global_logger().debug(
|
42
42
|
f"ProtocolMiddleware - Error calling get_all(): {e}, type: {type(app_config)}"
|
43
43
|
)
|
44
44
|
normalized_config = None
|
45
45
|
elif hasattr(app_config, "keys"):
|
46
46
|
normalized_config = app_config # Already dict-like
|
47
47
|
else:
|
48
|
-
|
48
|
+
get_global_logger().debug(
|
49
49
|
f"ProtocolMiddleware - app_config is not dict-like, type: {type(app_config)}, value: {repr(app_config)}"
|
50
50
|
)
|
51
51
|
normalized_config = None
|
52
52
|
|
53
|
-
|
53
|
+
get_global_logger().debug(
|
54
54
|
f"ProtocolMiddleware - normalized_config type: {type(normalized_config)}"
|
55
55
|
)
|
56
56
|
if normalized_config:
|
57
|
-
|
57
|
+
get_global_logger().debug(
|
58
58
|
f"ProtocolMiddleware - protocols in config: {'protocols' in normalized_config}"
|
59
59
|
)
|
60
60
|
if "protocols" in normalized_config:
|
61
|
-
|
61
|
+
get_global_logger().debug(
|
62
62
|
f"ProtocolMiddleware - protocols type: {type(normalized_config['protocols'])}"
|
63
63
|
)
|
64
64
|
|
@@ -84,7 +84,7 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
84
84
|
else:
|
85
85
|
self.app_config = None
|
86
86
|
self.protocol_manager = get_protocol_manager(self.app_config)
|
87
|
-
|
87
|
+
get_global_logger().info("Protocol middleware configuration updated")
|
88
88
|
|
89
89
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
90
90
|
"""
|
@@ -97,19 +97,19 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
97
97
|
Returns:
|
98
98
|
Response object
|
99
99
|
"""
|
100
|
-
|
100
|
+
get_global_logger().debug(f"ProtocolMiddleware processing {request.method} {request.url.path}")
|
101
101
|
|
102
102
|
try:
|
103
103
|
# Get protocol from request
|
104
104
|
protocol = self._get_request_protocol(request)
|
105
|
-
|
105
|
+
get_global_logger().debug(f"Detected protocol: {protocol} for {request.method} {request.url.path}")
|
106
106
|
|
107
107
|
# Check if protocol is allowed
|
108
108
|
is_allowed = self.protocol_manager.is_protocol_allowed(protocol)
|
109
|
-
|
109
|
+
get_global_logger().debug(f"Protocol '{protocol}' allowed: {is_allowed}")
|
110
110
|
|
111
111
|
if not is_allowed:
|
112
|
-
|
112
|
+
get_global_logger().warning(f"Protocol '{protocol}' not allowed for request to {request.url.path}")
|
113
113
|
return JSONResponse(
|
114
114
|
status_code=403,
|
115
115
|
content={
|
@@ -121,14 +121,14 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
121
121
|
|
122
122
|
# Continue processing
|
123
123
|
request.state.protocol = protocol
|
124
|
-
|
124
|
+
get_global_logger().debug(f"Protocol '{protocol}' added to request state")
|
125
125
|
|
126
126
|
response = await call_next(request)
|
127
|
-
|
127
|
+
get_global_logger().debug(f"ProtocolMiddleware completed with status: {response.status_code}")
|
128
128
|
return response
|
129
129
|
|
130
130
|
except Exception as e:
|
131
|
-
|
131
|
+
get_global_logger().error(f"❌ PROTOCOL STEP ERROR: ProtocolMiddleware ERROR: {str(e)}", exc_info=True)
|
132
132
|
return JSONResponse(
|
133
133
|
status_code=500,
|
134
134
|
content={"error": "Protocol validation error", "message": str(e)},
|
@@ -163,7 +163,7 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
163
163
|
try:
|
164
164
|
cert = ssl_object.getpeercert()
|
165
165
|
if cert:
|
166
|
-
|
166
|
+
get_global_logger().debug(f"mTLS client certificate detected: {cert.get('subject', 'unknown')}")
|
167
167
|
return "mtls"
|
168
168
|
except Exception:
|
169
169
|
pass
|
@@ -181,7 +181,7 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
181
181
|
request.headers.get("x-forwarded-client-cert")
|
182
182
|
]
|
183
183
|
if any(mtls_headers):
|
184
|
-
|
184
|
+
get_global_logger().debug("mTLS client certificate detected in headers")
|
185
185
|
return "mtls"
|
186
186
|
except Exception:
|
187
187
|
pass
|
@@ -199,7 +199,7 @@ class ProtocolMiddleware(BaseHTTPMiddleware):
|
|
199
199
|
return "http"
|
200
200
|
|
201
201
|
except Exception as e:
|
202
|
-
|
202
|
+
get_global_logger().error(f"Error extracting protocol from request: {e}", exc_info=True)
|
203
203
|
# Fallback to HTTP if there's any error
|
204
204
|
return "http"
|
205
205
|
|
@@ -231,6 +231,6 @@ def setup_protocol_middleware(app, app_config: Optional[Dict[str, Any]] = None):
|
|
231
231
|
# Create protocol middleware with current configuration
|
232
232
|
middleware = ProtocolMiddleware(app, app_config)
|
233
233
|
app.add_middleware(ProtocolMiddleware, app_config=app_config)
|
234
|
-
|
234
|
+
get_global_logger().info("Protocol middleware added to application")
|
235
235
|
else:
|
236
|
-
|
236
|
+
get_global_logger().info("Protocol management is disabled, skipping protocol middleware")
|
@@ -10,7 +10,7 @@ from fastapi.responses import JSONResponse
|
|
10
10
|
from starlette.middleware.base import BaseHTTPMiddleware
|
11
11
|
|
12
12
|
from mcp_proxy_adapter.core.transport_manager import transport_manager
|
13
|
-
from mcp_proxy_adapter.core.logging import
|
13
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
14
14
|
|
15
15
|
|
16
16
|
class TransportMiddleware(BaseHTTPMiddleware):
|
@@ -47,7 +47,7 @@ class TransportMiddleware(BaseHTTPMiddleware):
|
|
47
47
|
configured_type_str = (
|
48
48
|
configured_type.value if configured_type else "not configured"
|
49
49
|
)
|
50
|
-
|
50
|
+
get_global_logger().warning(f"Transport not allowed: {transport_type} for {request.url}")
|
51
51
|
return JSONResponse(
|
52
52
|
status_code=403,
|
53
53
|
content={
|
@@ -118,7 +118,7 @@ class TransportMiddleware(BaseHTTPMiddleware):
|
|
118
118
|
"""
|
119
119
|
configured_type = self.transport_manager.get_transport_type()
|
120
120
|
if not configured_type:
|
121
|
-
|
121
|
+
get_global_logger().error("Transport not configured")
|
122
122
|
return False
|
123
123
|
|
124
124
|
return transport_type == configured_type.value
|
@@ -29,7 +29,7 @@ except ImportError:
|
|
29
29
|
SecurityManager = None
|
30
30
|
SecurityConfig = None
|
31
31
|
|
32
|
-
from mcp_proxy_adapter.core.logging import
|
32
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
33
33
|
from mcp_proxy_adapter.core.security_integration import create_security_integration
|
34
34
|
|
35
35
|
|
@@ -74,18 +74,18 @@ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
|
|
74
74
|
self.framework_middleware = (
|
75
75
|
self.security_integration.security_manager.create_fastapi_middleware()
|
76
76
|
)
|
77
|
-
|
77
|
+
get_global_logger().info("Using mcp_security_framework FastAPI middleware")
|
78
78
|
# IMPORTANT: Don't replace self.app! This breaks the middleware chain.
|
79
79
|
# Instead, store the framework middleware for use in dispatch method.
|
80
|
-
|
80
|
+
get_global_logger().info("Framework middleware will be used in dispatch method")
|
81
81
|
else:
|
82
|
-
|
82
|
+
get_global_logger().info("Security disabled, skipping mcp_security_framework integration")
|
83
83
|
self.security_integration = None
|
84
84
|
self.framework_middleware = None
|
85
85
|
except Exception as e:
|
86
|
-
|
86
|
+
get_global_logger().error(f"Security framework integration failed: {e}")
|
87
87
|
# Instead of raising error, log warning and continue without security
|
88
|
-
|
88
|
+
get_global_logger().warning(
|
89
89
|
"Continuing without security framework - some security features will be disabled"
|
90
90
|
)
|
91
91
|
self.security_integration = None
|
@@ -93,7 +93,7 @@ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
|
|
93
93
|
# Keep original app in place when framework middleware is unavailable
|
94
94
|
# BaseHTTPMiddleware initialized it via super().__init__(app)
|
95
95
|
|
96
|
-
|
96
|
+
get_global_logger().info("Unified security middleware initialized")
|
97
97
|
|
98
98
|
async def dispatch(
|
99
99
|
self, request: Request, call_next: Callable[[Request], Awaitable[Response]]
|
@@ -151,7 +151,7 @@ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
|
|
151
151
|
if self.framework_middleware:
|
152
152
|
# If framework middleware exists, we need to call it manually
|
153
153
|
# This is a workaround since we can't chain ASGI apps in BaseHTTPMiddleware
|
154
|
-
|
154
|
+
get_global_logger().debug(
|
155
155
|
"Framework middleware exists, continuing with regular call_next"
|
156
156
|
)
|
157
157
|
return await call_next(request)
|
@@ -164,7 +164,7 @@ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
|
|
164
164
|
return await self._handle_security_error(request, e)
|
165
165
|
except Exception as e:
|
166
166
|
# Handle other errors
|
167
|
-
|
167
|
+
get_global_logger().error(f"Unexpected error in unified security middleware: {e}")
|
168
168
|
return await self._handle_general_error(request, e)
|
169
169
|
|
170
170
|
async def _handle_security_error(
|
@@ -190,7 +190,7 @@ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
|
|
190
190
|
}
|
191
191
|
}
|
192
192
|
|
193
|
-
|
193
|
+
get_global_logger().warning(f"Security validation failed: {error.message}")
|
194
194
|
|
195
195
|
return JSONResponse(status_code=error.error_code, content=error_response)
|
196
196
|
|
@@ -217,6 +217,6 @@ class UnifiedSecurityMiddleware(BaseHTTPMiddleware):
|
|
217
217
|
}
|
218
218
|
}
|
219
219
|
|
220
|
-
|
220
|
+
get_global_logger().error(f"General error in security middleware: {error}")
|
221
221
|
|
222
222
|
return JSONResponse(status_code=500, content=error_response)
|
@@ -12,7 +12,7 @@ from typing import Dict, Any, Callable, Awaitable
|
|
12
12
|
from fastapi import Request, Response
|
13
13
|
from starlette.middleware.base import BaseHTTPMiddleware
|
14
14
|
|
15
|
-
from mcp_proxy_adapter.core.logging import
|
15
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
16
16
|
|
17
17
|
# Import mcp_security_framework components
|
18
18
|
try:
|
@@ -57,7 +57,7 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
57
57
|
# Check if security is enabled
|
58
58
|
security_enabled = security_config.get("enabled", False)
|
59
59
|
if not security_enabled:
|
60
|
-
|
60
|
+
get_global_logger().info("ℹ️ Security disabled in configuration, using basic auth")
|
61
61
|
self._security_available = False
|
62
62
|
else:
|
63
63
|
auth_config = security_config.get("auth", {})
|
@@ -78,7 +78,7 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
78
78
|
# Create PermissionConfig for mcp_security_framework
|
79
79
|
roles_file = permissions_config.get("roles_file")
|
80
80
|
if roles_file is None:
|
81
|
-
|
81
|
+
get_global_logger().warning("⚠️ Permissions enabled but no roles_file specified, using default configuration")
|
82
82
|
roles_file = None
|
83
83
|
|
84
84
|
mcp_permission_config = PermissionConfig(
|
@@ -106,17 +106,17 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
106
106
|
self.auth_manager = AuthManager(
|
107
107
|
mcp_auth_config, self.permission_manager
|
108
108
|
)
|
109
|
-
|
109
|
+
get_global_logger().info(
|
110
110
|
"✅ User info middleware initialized with " "mcp_security_framework"
|
111
111
|
)
|
112
112
|
else:
|
113
113
|
# When permissions are disabled, use basic auth without mcp_security_framework
|
114
|
-
|
114
|
+
get_global_logger().info("ℹ️ Permissions disabled, using basic token auth without mcp_security_framework")
|
115
115
|
self._security_available = False
|
116
116
|
# Initialize api_keys for basic auth
|
117
117
|
self.api_keys = auth_config.get("api_keys", {})
|
118
118
|
except Exception as e:
|
119
|
-
|
119
|
+
get_global_logger().warning(f"⚠️ Failed to initialize AuthManager: {e}")
|
120
120
|
self._security_available = False
|
121
121
|
|
122
122
|
# Always initialize api_keys for fallback
|
@@ -126,9 +126,9 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
126
126
|
|
127
127
|
if not self._security_available:
|
128
128
|
# Fallback to basic API key handling
|
129
|
-
|
129
|
+
get_global_logger().info("ℹ️ User info middleware initialized with basic auth")
|
130
130
|
else:
|
131
|
-
|
131
|
+
get_global_logger().info("ℹ️ User info middleware initialized with mcp_security_framework (fallback enabled)")
|
132
132
|
|
133
133
|
async def dispatch(
|
134
134
|
self, request: Request, call_next: Callable[[Request], Awaitable[Response]]
|
@@ -143,14 +143,14 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
143
143
|
Returns:
|
144
144
|
Response object
|
145
145
|
"""
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
146
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware.dispatch START - {request.method} {request.url.path}")
|
147
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware - Headers: {dict(request.headers)}")
|
148
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware - AuthManager available: {self.auth_manager is not None}")
|
149
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware - Security available: {self._security_available}")
|
150
150
|
|
151
151
|
# Extract API key from headers
|
152
152
|
api_key = request.headers.get("X-API-Key")
|
153
|
-
|
153
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware - API Key: {api_key[:8] + '...' if api_key else 'None'}")
|
154
154
|
if api_key:
|
155
155
|
if self.auth_manager and self._security_available:
|
156
156
|
try:
|
@@ -169,7 +169,7 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
169
169
|
auth_result, "permissions", ["read"]
|
170
170
|
),
|
171
171
|
}
|
172
|
-
|
172
|
+
get_global_logger().debug(
|
173
173
|
f"✅ Authenticated user with "
|
174
174
|
f"mcp_security_framework: "
|
175
175
|
f"{request.state.user}"
|
@@ -182,12 +182,12 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
182
182
|
"roles": ["guest"],
|
183
183
|
"permissions": ["read"],
|
184
184
|
}
|
185
|
-
|
185
|
+
get_global_logger().debug(
|
186
186
|
f"❌ Authentication failed for API key: "
|
187
187
|
f"{api_key[:8]}..."
|
188
188
|
)
|
189
189
|
except Exception as e:
|
190
|
-
|
190
|
+
get_global_logger().warning(
|
191
191
|
f"⚠️ AuthManager error: {e}, " f"falling back to basic auth"
|
192
192
|
)
|
193
193
|
self._security_available = False
|
@@ -221,7 +221,7 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
221
221
|
"roles": [user_role],
|
222
222
|
"permissions": role_permissions,
|
223
223
|
}
|
224
|
-
|
224
|
+
get_global_logger().debug(
|
225
225
|
f"✅ User authenticated with API key: "
|
226
226
|
f"{api_key[:8]}..."
|
227
227
|
)
|
@@ -233,7 +233,7 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
233
233
|
"roles": ["guest"],
|
234
234
|
"permissions": ["read"],
|
235
235
|
}
|
236
|
-
|
236
|
+
get_global_logger().debug(f"❌ API key not found: {api_key[:8]}...")
|
237
237
|
else:
|
238
238
|
# No API key provided - guest access
|
239
239
|
request.state.user = {
|
@@ -242,9 +242,9 @@ class UserInfoMiddleware(BaseHTTPMiddleware):
|
|
242
242
|
"roles": ["guest"],
|
243
243
|
"permissions": ["read"],
|
244
244
|
}
|
245
|
-
|
245
|
+
get_global_logger().debug("ℹ️ No API key provided, using guest access")
|
246
246
|
|
247
|
-
|
247
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware - About to call next handler")
|
248
248
|
response = await call_next(request)
|
249
|
-
|
249
|
+
get_global_logger().debug(f"🔍 UserInfoMiddleware - Next handler completed with status: {response.status_code}")
|
250
250
|
return response
|
@@ -13,6 +13,7 @@ import logging
|
|
13
13
|
from mcp_proxy_adapter.api.schemas import APIToolDescription
|
14
14
|
from mcp_proxy_adapter.commands.command_registry import CommandRegistry
|
15
15
|
|
16
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
16
17
|
logger = logging.getLogger(__name__)
|
17
18
|
|
18
19
|
|
@@ -138,9 +139,9 @@ class ToolIntegration:
|
|
138
139
|
|
139
140
|
results[tool_name] = {"status": "success", "schema": schema}
|
140
141
|
|
141
|
-
|
142
|
+
get_global_logger().info(f"Successfully registered tool: {tool_name}")
|
142
143
|
except Exception as e:
|
143
|
-
|
144
|
+
get_global_logger().debug(f"Error registering tool {tool_name}: {e}")
|
144
145
|
results[tool_name] = {"status": "error", "error": str(e)}
|
145
146
|
|
146
147
|
return results
|
mcp_proxy_adapter/api/tools.py
CHANGED
@@ -13,6 +13,7 @@ from mcp_proxy_adapter.api.tool_integration import ToolIntegration
|
|
13
13
|
from mcp_proxy_adapter.commands.command_registry import registry
|
14
14
|
from mcp_proxy_adapter.core.errors import NotFoundError, InvalidParamsError
|
15
15
|
|
16
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
16
17
|
logger = logging.getLogger(__name__)
|
17
18
|
|
18
19
|
|
@@ -48,7 +49,7 @@ class TSTCommandExecutor:
|
|
48
49
|
if not params:
|
49
50
|
params = {}
|
50
51
|
|
51
|
-
|
52
|
+
get_global_logger().info(f"Executing command via TST: {command}, params: {params}")
|
52
53
|
|
53
54
|
try:
|
54
55
|
# Проверяем существование команды
|
@@ -64,10 +65,10 @@ class TSTCommandExecutor:
|
|
64
65
|
# Возвращаем результат
|
65
66
|
return result.to_dict()
|
66
67
|
except NotFoundError as e:
|
67
|
-
|
68
|
+
get_global_logger().error(f"Command not found: {command}")
|
68
69
|
raise
|
69
70
|
except Exception as e:
|
70
|
-
|
71
|
+
get_global_logger().exception(f"Error executing command {command}: {e}")
|
71
72
|
raise
|
72
73
|
|
73
74
|
@classmethod
|
@@ -20,6 +20,7 @@ from ..commands.result import SuccessResult, ErrorResult
|
|
20
20
|
from ..core.auth_validator import AuthValidator, AuthValidationResult
|
21
21
|
|
22
22
|
|
23
|
+
from mcp_proxy_adapter.core.logging import get_global_logger
|
23
24
|
class AuthValidationCommand(Command):
|
24
25
|
"""
|
25
26
|
Authentication validation commands.
|
@@ -74,7 +75,7 @@ class AuthValidationCommand(Command):
|
|
74
75
|
)
|
75
76
|
|
76
77
|
except Exception as e:
|
77
|
-
self.
|
78
|
+
self.get_global_logger().error(f"Authentication validation error: {e}")
|
78
79
|
return ErrorResult(
|
79
80
|
message=f"Internal authentication validation error: {str(e)}",
|
80
81
|
code=-32603,
|
@@ -115,7 +116,7 @@ class AuthValidationCommand(Command):
|
|
115
116
|
)
|
116
117
|
|
117
118
|
except Exception as e:
|
118
|
-
self.
|
119
|
+
self.get_global_logger().error(f"Certificate validation error: {e}")
|
119
120
|
return ErrorResult(
|
120
121
|
message=f"Internal certificate validation error: {str(e)}", code=-32603
|
121
122
|
)
|
@@ -154,7 +155,7 @@ class AuthValidationCommand(Command):
|
|
154
155
|
)
|
155
156
|
|
156
157
|
except Exception as e:
|
157
|
-
self.
|
158
|
+
self.get_global_logger().error(f"Token validation error: {e}")
|
158
159
|
return ErrorResult(
|
159
160
|
message=f"Internal token validation error: {str(e)}", code=-32603
|
160
161
|
)
|
@@ -194,7 +195,7 @@ class AuthValidationCommand(Command):
|
|
194
195
|
)
|
195
196
|
|
196
197
|
except Exception as e:
|
197
|
-
self.
|
198
|
+
self.get_global_logger().error(f"mTLS validation error: {e}")
|
198
199
|
return ErrorResult(
|
199
200
|
message=f"Internal mTLS validation error: {str(e)}", code=-32603
|
200
201
|
)
|
@@ -232,7 +233,7 @@ class AuthValidationCommand(Command):
|
|
232
233
|
)
|
233
234
|
|
234
235
|
except Exception as e:
|
235
|
-
self.
|
236
|
+
self.get_global_logger().error(f"SSL validation error: {e}")
|
236
237
|
return ErrorResult(
|
237
238
|
message=f"Internal SSL validation error: {str(e)}", code=-32603
|
238
239
|
)
|