mcpower-proxy 0.0.68__tar.gz → 0.0.70__tar.gz
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.
Potentially problematic release.
This version of mcpower-proxy might be problematic. Click here for more details.
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/PKG-INFO +2 -2
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/pyproject.toml +2 -2
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/PKG-INFO +2 -2
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/requires.txt +1 -1
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/apis/security_policy.py +1 -1
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/wrapper/__version__.py +1 -1
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/wrapper/middleware.py +57 -21
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/wrapper/server.py +19 -11
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/LICENSE +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/README.md +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/setup.cfg +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/LICENSE +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/main.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/SOURCES.txt +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/dependency_links.txt +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/entry_points.txt +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/top_level.txt +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/apis/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/logs/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/logs/audit_trail.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/logs/logger.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/redaction/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/redaction/constants.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/redaction/gitleaks_rules.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/redaction/pii_rules.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/redaction/redactor.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/classes.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/confirmation.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/simple_dialog.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/constants.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/mac_dialogs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/tk_dialogs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/windows_custom_dialog.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/windows_dialogs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/windows_structs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/yad_dialogs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/zenity_dialogs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/cli.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/config.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/copy.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/ids.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/json.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/utils/mcp_configs.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/wrapper/__init__.py +0 -0
- {mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/wrapper/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcpower-proxy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.70
|
|
4
4
|
Summary: MCPower Security proxy
|
|
5
5
|
Author-email: MCPower Security <support@mcpower.tech>
|
|
6
6
|
License: Apache License
|
|
@@ -209,7 +209,7 @@ Keywords: mcp,security,proxy,monitoring,audit,redaction,policy-enforcement
|
|
|
209
209
|
Requires-Python: ~=3.11.0
|
|
210
210
|
Description-Content-Type: text/markdown
|
|
211
211
|
License-File: LICENSE
|
|
212
|
-
Requires-Dist: fastmcp==2.13.0.
|
|
212
|
+
Requires-Dist: fastmcp==2.13.0.2
|
|
213
213
|
Requires-Dist: httpx>=0.25.0
|
|
214
214
|
Requires-Dist: mcp>=1.0.0
|
|
215
215
|
Requires-Dist: watchdog>=3.0.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mcpower-proxy"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.70"
|
|
4
4
|
description = "MCPower Security proxy"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = "~=3.11.0"
|
|
@@ -9,7 +9,7 @@ authors = [
|
|
|
9
9
|
{ name = "MCPower Security", email = "support@mcpower.tech" }
|
|
10
10
|
]
|
|
11
11
|
dependencies = [
|
|
12
|
-
"fastmcp==2.13.0.
|
|
12
|
+
"fastmcp==2.13.0.2",
|
|
13
13
|
"httpx>=0.25.0",
|
|
14
14
|
"mcp>=1.0.0",
|
|
15
15
|
"watchdog>=3.0.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcpower-proxy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.70
|
|
4
4
|
Summary: MCPower Security proxy
|
|
5
5
|
Author-email: MCPower Security <support@mcpower.tech>
|
|
6
6
|
License: Apache License
|
|
@@ -209,7 +209,7 @@ Keywords: mcp,security,proxy,monitoring,audit,redaction,policy-enforcement
|
|
|
209
209
|
Requires-Python: ~=3.11.0
|
|
210
210
|
Description-Content-Type: text/markdown
|
|
211
211
|
License-File: LICENSE
|
|
212
|
-
Requires-Dist: fastmcp==2.13.0.
|
|
212
|
+
Requires-Dist: fastmcp==2.13.0.2
|
|
213
213
|
Requires-Dist: httpx>=0.25.0
|
|
214
214
|
Requires-Dist: mcp>=1.0.0
|
|
215
215
|
Requires-Dist: watchdog>=3.0.0
|
|
@@ -190,7 +190,7 @@ class SecurityPolicyClient:
|
|
|
190
190
|
raise SecurityAPIError(f"Unsupported HTTP method: {method}. Supported methods: POST, PUT")
|
|
191
191
|
|
|
192
192
|
on_make_request_duration = time.time() - on_make_request_start_time
|
|
193
|
-
self.logger.
|
|
193
|
+
self.logger.debug(f"PROFILE: {method} id: {id} make_request duration: {on_make_request_duration:.2f} seconds url: {url}")
|
|
194
194
|
|
|
195
195
|
match response.status_code:
|
|
196
196
|
case 200:
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
FastMCP middleware for security policy enforcement
|
|
3
3
|
Implements pre/post interception for all MCP operations
|
|
4
4
|
"""
|
|
5
|
+
import asyncio
|
|
5
6
|
import sys
|
|
6
7
|
import time
|
|
7
8
|
import urllib.parse
|
|
@@ -12,6 +13,8 @@ from typing import Any, Dict, List, Optional
|
|
|
12
13
|
from fastmcp.exceptions import FastMCPError
|
|
13
14
|
from fastmcp.server.middleware.middleware import Middleware, MiddlewareContext, CallNext
|
|
14
15
|
from fastmcp.server.proxy import ProxyClient
|
|
16
|
+
from httpx import HTTPStatusError
|
|
17
|
+
from mcp import ErrorData
|
|
15
18
|
|
|
16
19
|
from mcpower_shared.mcp_types import (create_policy_request, create_policy_response, AgentContext, EnvironmentContext,
|
|
17
20
|
InitRequest,
|
|
@@ -53,10 +56,7 @@ class MockContext:
|
|
|
53
56
|
class SecurityMiddleware(Middleware):
|
|
54
57
|
"""FastMCP middleware for security policy enforcement"""
|
|
55
58
|
|
|
56
|
-
app_id: str = ""
|
|
57
59
|
_TOOLS_INIT_DEBOUNCE_SECONDS = 60
|
|
58
|
-
_last_tools_init_time: Optional[float] = None
|
|
59
|
-
_last_workspace_root: Optional[str] = None
|
|
60
60
|
|
|
61
61
|
def __init__(self,
|
|
62
62
|
wrapped_server_configs: dict,
|
|
@@ -72,6 +72,9 @@ class SecurityMiddleware(Middleware):
|
|
|
72
72
|
self.audit_logger = audit_logger
|
|
73
73
|
self.app_id = ""
|
|
74
74
|
self._last_workspace_root = None
|
|
75
|
+
self._last_tools_init_time: Optional[float] = None
|
|
76
|
+
self._tools_list_in_progress: Optional[asyncio.Task] = None
|
|
77
|
+
self._tools_list_lock = asyncio.Lock()
|
|
75
78
|
|
|
76
79
|
self.wrapped_server_name, self.wrapped_server_transport = (
|
|
77
80
|
extract_wrapped_server_info(self.wrapper_server_name, self.logger, self.wrapped_server_configs)
|
|
@@ -96,13 +99,28 @@ class SecurityMiddleware(Middleware):
|
|
|
96
99
|
workspace_roots = await self._extract_workspace_roots(context)
|
|
97
100
|
current_workspace_root = workspace_roots[0] if workspace_roots else str(Path.home() / ".mcpower")
|
|
98
101
|
if current_workspace_root != self._last_workspace_root:
|
|
99
|
-
self.logger.debug(
|
|
102
|
+
self.logger.debug(
|
|
103
|
+
f"Workspace root changed from {self._last_workspace_root} to {current_workspace_root}")
|
|
100
104
|
self._last_workspace_root = current_workspace_root
|
|
101
105
|
self.app_id = read_app_uid(logger=self.logger, project_folder_path=current_workspace_root)
|
|
102
106
|
self.audit_logger.set_app_uid(self.app_id)
|
|
103
107
|
|
|
104
108
|
operation_type = "message"
|
|
105
|
-
|
|
109
|
+
|
|
110
|
+
async def call_next_wrapper(ctx):
|
|
111
|
+
try:
|
|
112
|
+
return await call_next(ctx)
|
|
113
|
+
except HTTPStatusError as e:
|
|
114
|
+
if e.response.status_code in (401, 403):
|
|
115
|
+
raise FastMCPError(ErrorData(
|
|
116
|
+
code=-32000,
|
|
117
|
+
message="Authentication required",
|
|
118
|
+
data={
|
|
119
|
+
"type": "unauthorized",
|
|
120
|
+
"details": "Please provide valid authentication credentials"
|
|
121
|
+
}
|
|
122
|
+
))
|
|
123
|
+
raise e
|
|
106
124
|
|
|
107
125
|
match context.type:
|
|
108
126
|
case "request":
|
|
@@ -119,13 +137,13 @@ class SecurityMiddleware(Middleware):
|
|
|
119
137
|
operation_type = "prompt"
|
|
120
138
|
case "tools/list":
|
|
121
139
|
# Special handling for tools/list - call /init instead of normal inspection
|
|
122
|
-
return await self._handle_tools_list(context,
|
|
140
|
+
return await self._handle_tools_list(context, call_next_wrapper)
|
|
123
141
|
case "initialize" | "resources/list" | "resources/templates/list" | "prompts/list":
|
|
124
|
-
return await
|
|
142
|
+
return await call_next_wrapper(context)
|
|
125
143
|
|
|
126
144
|
return await self._handle_operation(
|
|
127
145
|
context=context,
|
|
128
|
-
call_next=
|
|
146
|
+
call_next=call_next_wrapper,
|
|
129
147
|
error_class=FastMCPError,
|
|
130
148
|
operation_type=operation_type
|
|
131
149
|
)
|
|
@@ -185,7 +203,7 @@ class SecurityMiddleware(Middleware):
|
|
|
185
203
|
return await ProxyClient.default_progress_handler(progress, total, message)
|
|
186
204
|
|
|
187
205
|
async def secure_log_handler(self, log_message):
|
|
188
|
-
# FIXME: log_message should be redacted before logging,
|
|
206
|
+
# FIXME: log_message should be redacted before logging,
|
|
189
207
|
self.logger.info(f"secure_log_handler: {str(log_message)[:100]}...")
|
|
190
208
|
# FIXME: log_message should be reviewed with policy before forwarding
|
|
191
209
|
|
|
@@ -226,7 +244,8 @@ class SecurityMiddleware(Middleware):
|
|
|
226
244
|
prompt_id=prompt_id
|
|
227
245
|
)
|
|
228
246
|
on_inspect_request_duration = time.time() - on_inspect_request_start_time
|
|
229
|
-
self.logger.
|
|
247
|
+
self.logger.debug(
|
|
248
|
+
f"PROFILE: {operation_type} id: {event_id} inspect_request duration: {on_inspect_request_duration:.2f} seconds")
|
|
230
249
|
|
|
231
250
|
await self._enforce_decision(
|
|
232
251
|
decision=request_decision,
|
|
@@ -255,7 +274,8 @@ class SecurityMiddleware(Middleware):
|
|
|
255
274
|
# Call wrapped MCP with cleaned context (e.g., no wrapper args)
|
|
256
275
|
result = await call_next(cleaned_context)
|
|
257
276
|
on_call_next_duration = time.time() - on_call_next_start_time
|
|
258
|
-
self.logger.
|
|
277
|
+
self.logger.debug(
|
|
278
|
+
f"PROFILE: {operation_type} id: {event_id} call_next duration: {on_call_next_duration:.2f} seconds")
|
|
259
279
|
|
|
260
280
|
response_content = self._extract_response_content(result)
|
|
261
281
|
|
|
@@ -280,7 +300,8 @@ class SecurityMiddleware(Middleware):
|
|
|
280
300
|
prompt_id=prompt_id
|
|
281
301
|
)
|
|
282
302
|
on_inspect_response_duration = time.time() - on_inspect_response_start_time
|
|
283
|
-
self.logger.
|
|
303
|
+
self.logger.debug(
|
|
304
|
+
f"PROFILE: {operation_type} id: {event_id} inspect_response duration: {on_inspect_response_duration:.2f} seconds")
|
|
284
305
|
|
|
285
306
|
await self._enforce_decision(
|
|
286
307
|
decision=response_decision,
|
|
@@ -305,15 +326,30 @@ class SecurityMiddleware(Middleware):
|
|
|
305
326
|
prompt_id=prompt_id
|
|
306
327
|
)
|
|
307
328
|
on_handle_operation_duration = time.time() - on_handle_operation_start_time
|
|
308
|
-
self.logger.
|
|
329
|
+
self.logger.debug(
|
|
330
|
+
f"PROFILE: {operation_type} id: {event_id} duration: {on_handle_operation_duration:.2f} seconds")
|
|
309
331
|
return result
|
|
310
332
|
|
|
311
333
|
async def _handle_tools_list(self, context: MiddlewareContext, call_next: CallNext) -> Any:
|
|
312
|
-
"""Handle tools/list by calling /init API and modifying schemas"""
|
|
334
|
+
"""Handle tools/list by calling /init API and modifying schemas with deduplication"""
|
|
313
335
|
event_id = generate_event_id()
|
|
314
336
|
on_handle_tools_list_start_time = time.time()
|
|
315
|
-
|
|
316
|
-
|
|
337
|
+
|
|
338
|
+
async with self._tools_list_lock:
|
|
339
|
+
if not self._tools_list_in_progress or self._tools_list_in_progress.done():
|
|
340
|
+
self._tools_list_in_progress = asyncio.create_task(call_next(context))
|
|
341
|
+
shared_task = self._tools_list_in_progress
|
|
342
|
+
|
|
343
|
+
try:
|
|
344
|
+
result = await shared_task
|
|
345
|
+
except Exception as e:
|
|
346
|
+
async with self._tools_list_lock:
|
|
347
|
+
if self._tools_list_in_progress is shared_task:
|
|
348
|
+
self._tools_list_in_progress = None
|
|
349
|
+
raise
|
|
350
|
+
self.logger.debug(
|
|
351
|
+
f"PROFILE: tools/list call_next duration: {time.time() - on_handle_tools_list_start_time:.2f} seconds id: {event_id}")
|
|
352
|
+
|
|
317
353
|
tools_list = None
|
|
318
354
|
if isinstance(result, list):
|
|
319
355
|
tools_list = result
|
|
@@ -343,11 +379,13 @@ class SecurityMiddleware(Middleware):
|
|
|
343
379
|
enhanced_result = result
|
|
344
380
|
|
|
345
381
|
on_handle_tools_list_duration = time.time() - on_handle_tools_list_start_time
|
|
346
|
-
self.logger.
|
|
382
|
+
self.logger.debug(
|
|
383
|
+
f"PROFILE: tools/list enhanced_result duration: {on_handle_tools_list_duration:.2f} seconds id: {event_id}")
|
|
347
384
|
return enhanced_result
|
|
348
385
|
|
|
349
386
|
on_handle_tools_list_duration = time.time() - on_handle_tools_list_start_time
|
|
350
|
-
self.logger.
|
|
387
|
+
self.logger.debug(
|
|
388
|
+
f"PROFILE: tools/list result duration: {on_handle_tools_list_duration:.2f} seconds id: {event_id}")
|
|
351
389
|
|
|
352
390
|
return result
|
|
353
391
|
|
|
@@ -618,7 +656,6 @@ class SecurityMiddleware(Middleware):
|
|
|
618
656
|
# Don't fail the operation if API call fails - just log the error
|
|
619
657
|
self.logger.error(f"Failed to record user confirmation: {e}")
|
|
620
658
|
|
|
621
|
-
|
|
622
659
|
@staticmethod
|
|
623
660
|
def _create_security_api_failure_decision(error: Exception) -> Dict[str, Any]:
|
|
624
661
|
"""Create a standard failure decision when security API is unavailable/failing/unreachable"""
|
|
@@ -726,7 +763,7 @@ class SecurityMiddleware(Middleware):
|
|
|
726
763
|
error_parts = [
|
|
727
764
|
f"SECURITY POLICY NEEDS MORE INFORMATION FOR REVIEWING {stage_title}:",
|
|
728
765
|
'\n'.join(reasons),
|
|
729
|
-
''
|
|
766
|
+
'' # newline
|
|
730
767
|
]
|
|
731
768
|
|
|
732
769
|
if need_fields:
|
|
@@ -753,7 +790,6 @@ class SecurityMiddleware(Middleware):
|
|
|
753
790
|
error_parts.append("MISSING INFORMATION:")
|
|
754
791
|
error_parts.extend(need_fields)
|
|
755
792
|
|
|
756
|
-
|
|
757
793
|
error_parts.append("\nMANDATORY ACTIONS:")
|
|
758
794
|
error_parts.append("1. Add/Edit ALL affected fields according to the required information")
|
|
759
795
|
error_parts.append("2. Retry the tool call")
|
|
@@ -6,10 +6,11 @@ Implements transparent 1:1 MCP proxying with security middleware
|
|
|
6
6
|
import logging
|
|
7
7
|
|
|
8
8
|
from fastmcp.server.middleware.logging import StructuredLoggingMiddleware
|
|
9
|
-
from fastmcp.server.proxy import ProxyClient, default_proxy_roots_handler, FastMCPProxy
|
|
9
|
+
from fastmcp.server.proxy import ProxyClient, default_proxy_roots_handler, FastMCPProxy, StatefulProxyClient
|
|
10
10
|
|
|
11
11
|
from modules.logs.audit_trail import AuditTrailLogger
|
|
12
12
|
from modules.logs.logger import MCPLogger
|
|
13
|
+
from modules.utils.json import safe_json_dumps
|
|
13
14
|
from .__version__ import __version__
|
|
14
15
|
from .middleware import SecurityMiddleware
|
|
15
16
|
|
|
@@ -42,7 +43,7 @@ def create_wrapper_server(wrapper_server_name: str,
|
|
|
42
43
|
logger=logger,
|
|
43
44
|
audit_logger=audit_logger
|
|
44
45
|
)
|
|
45
|
-
|
|
46
|
+
|
|
46
47
|
# Log MCPower startup to audit trail
|
|
47
48
|
audit_logger.log_event("mcpower_start", {
|
|
48
49
|
"wrapper_version": __version__,
|
|
@@ -51,16 +52,23 @@ def create_wrapper_server(wrapper_server_name: str,
|
|
|
51
52
|
})
|
|
52
53
|
|
|
53
54
|
# Create FastMCP server as proxy with our security-aware ProxyClient
|
|
55
|
+
# Use StatefulProxyClient for remote servers (mcp-remote or url-based transports)
|
|
56
|
+
config_str = safe_json_dumps(wrapped_server_configs)
|
|
57
|
+
is_remote = '"@mcpower/mcp-remote",' in config_str or '"url":' in config_str
|
|
58
|
+
backend_class = StatefulProxyClient if is_remote else ProxyClient
|
|
59
|
+
backend = backend_class(
|
|
60
|
+
wrapped_server_configs,
|
|
61
|
+
name=wrapper_server_name,
|
|
62
|
+
roots=default_proxy_roots_handler, # Use default for filesystem roots
|
|
63
|
+
sampling_handler=security_middleware.secure_sampling_handler,
|
|
64
|
+
elicitation_handler=security_middleware.secure_elicitation_handler,
|
|
65
|
+
log_handler=security_middleware.secure_log_handler,
|
|
66
|
+
progress_handler=security_middleware.secure_progress_handler,
|
|
67
|
+
)
|
|
68
|
+
|
|
54
69
|
def client_factory():
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
name=wrapper_server_name,
|
|
58
|
-
roots=default_proxy_roots_handler, # Use default for filesystem roots
|
|
59
|
-
sampling_handler=security_middleware.secure_sampling_handler,
|
|
60
|
-
elicitation_handler=security_middleware.secure_elicitation_handler,
|
|
61
|
-
log_handler=security_middleware.secure_log_handler,
|
|
62
|
-
progress_handler=security_middleware.secure_progress_handler,
|
|
63
|
-
)
|
|
70
|
+
# we must return the same instance, otherwise StatefulProxyClient doesn't play nice with mcp-remote
|
|
71
|
+
return backend
|
|
64
72
|
|
|
65
73
|
server = FastMCPProxy(client_factory=client_factory, name=wrapper_server_name, version=__version__)
|
|
66
74
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/mcpower_proxy.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mcpower_proxy-0.0.68 → mcpower_proxy-0.0.70}/src/modules/ui/xdialog/windows_custom_dialog.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|