Spaces:
Paused
Paused
Merge branch 'pr/693' into development
Browse files
python/helpers/mcp_handler.py
CHANGED
|
@@ -24,6 +24,8 @@ import json
|
|
| 24 |
from python.helpers import errors
|
| 25 |
from python.helpers import settings
|
| 26 |
|
|
|
|
|
|
|
| 27 |
from mcp import ClientSession, StdioServerParameters
|
| 28 |
from mcp.client.stdio import stdio_client
|
| 29 |
from mcp.client.sse import sse_client
|
|
@@ -216,6 +218,7 @@ class MCPServerRemote(BaseModel):
|
|
| 216 |
headers: dict[str, Any] | None = Field(default_factory=dict[str, Any])
|
| 217 |
init_timeout: int = Field(default=0)
|
| 218 |
tool_timeout: int = Field(default=0)
|
|
|
|
| 219 |
disabled: bool = Field(default=False)
|
| 220 |
|
| 221 |
__lock: ClassVar[threading.Lock] = PrivateAttr(default=threading.Lock())
|
|
@@ -265,6 +268,7 @@ class MCPServerRemote(BaseModel):
|
|
| 265 |
"init_timeout",
|
| 266 |
"tool_timeout",
|
| 267 |
"disabled",
|
|
|
|
| 268 |
]:
|
| 269 |
if key == "name":
|
| 270 |
value = normalize_name(value)
|
|
@@ -293,6 +297,7 @@ class MCPServerLocal(BaseModel):
|
|
| 293 |
)
|
| 294 |
init_timeout: int = Field(default=0)
|
| 295 |
tool_timeout: int = Field(default=0)
|
|
|
|
| 296 |
disabled: bool = Field(default=False)
|
| 297 |
|
| 298 |
__lock: ClassVar[threading.Lock] = PrivateAttr(default=threading.Lock())
|
|
@@ -1018,6 +1023,36 @@ class MCPClientLocal(MCPClientBase):
|
|
| 1018 |
# do not read or close the file here, as stdio is async
|
| 1019 |
return stdio_transport
|
| 1020 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1021 |
|
| 1022 |
class MCPClientRemote(MCPClientBase):
|
| 1023 |
|
|
@@ -1040,6 +1075,7 @@ class MCPClientRemote(MCPClientBase):
|
|
| 1040 |
init_timeout = min(server.init_timeout or set["mcp_client_init_timeout"], 5)
|
| 1041 |
tool_timeout = min(server.tool_timeout or set["mcp_client_tool_timeout"], 10)
|
| 1042 |
|
|
|
|
| 1043 |
# Check if this is a streaming HTTP type
|
| 1044 |
if _is_streaming_http_type(server.type):
|
| 1045 |
# Use streamable HTTP client
|
|
@@ -1049,6 +1085,7 @@ class MCPClientRemote(MCPClientBase):
|
|
| 1049 |
headers=server.headers,
|
| 1050 |
timeout=timedelta(seconds=init_timeout),
|
| 1051 |
sse_read_timeout=timedelta(seconds=tool_timeout),
|
|
|
|
| 1052 |
)
|
| 1053 |
)
|
| 1054 |
# streamablehttp_client returns (read_stream, write_stream, get_session_id_callback)
|
|
@@ -1066,6 +1103,7 @@ class MCPClientRemote(MCPClientBase):
|
|
| 1066 |
headers=server.headers,
|
| 1067 |
timeout=init_timeout,
|
| 1068 |
sse_read_timeout=tool_timeout,
|
|
|
|
| 1069 |
)
|
| 1070 |
)
|
| 1071 |
return stdio_transport
|
|
|
|
| 24 |
from python.helpers import errors
|
| 25 |
from python.helpers import settings
|
| 26 |
|
| 27 |
+
import httpx
|
| 28 |
+
|
| 29 |
from mcp import ClientSession, StdioServerParameters
|
| 30 |
from mcp.client.stdio import stdio_client
|
| 31 |
from mcp.client.sse import sse_client
|
|
|
|
| 218 |
headers: dict[str, Any] | None = Field(default_factory=dict[str, Any])
|
| 219 |
init_timeout: int = Field(default=0)
|
| 220 |
tool_timeout: int = Field(default=0)
|
| 221 |
+
verify: bool = Field(default=True, description="Verify SSL certificates")
|
| 222 |
disabled: bool = Field(default=False)
|
| 223 |
|
| 224 |
__lock: ClassVar[threading.Lock] = PrivateAttr(default=threading.Lock())
|
|
|
|
| 268 |
"init_timeout",
|
| 269 |
"tool_timeout",
|
| 270 |
"disabled",
|
| 271 |
+
"verify",
|
| 272 |
]:
|
| 273 |
if key == "name":
|
| 274 |
value = normalize_name(value)
|
|
|
|
| 297 |
)
|
| 298 |
init_timeout: int = Field(default=0)
|
| 299 |
tool_timeout: int = Field(default=0)
|
| 300 |
+
verify: bool = Field(default=True, description="Verify SSL certificates")
|
| 301 |
disabled: bool = Field(default=False)
|
| 302 |
|
| 303 |
__lock: ClassVar[threading.Lock] = PrivateAttr(default=threading.Lock())
|
|
|
|
| 1023 |
# do not read or close the file here, as stdio is async
|
| 1024 |
return stdio_transport
|
| 1025 |
|
| 1026 |
+
class CustomHTTPClientFactory(ABC):
|
| 1027 |
+
def __init__(self, verify: bool = True):
|
| 1028 |
+
self.verify = verify
|
| 1029 |
+
|
| 1030 |
+
def __call__(
|
| 1031 |
+
self,
|
| 1032 |
+
headers: dict[str, str] | None = None,
|
| 1033 |
+
timeout: httpx.Timeout | None = None,
|
| 1034 |
+
auth: httpx.Auth | None = None,
|
| 1035 |
+
) -> httpx.AsyncClient:
|
| 1036 |
+
# Set MCP defaults
|
| 1037 |
+
kwargs: dict[str, Any] = {
|
| 1038 |
+
"follow_redirects": True,
|
| 1039 |
+
}
|
| 1040 |
+
|
| 1041 |
+
# Handle timeout
|
| 1042 |
+
if timeout is None:
|
| 1043 |
+
kwargs["timeout"] = httpx.Timeout(30.0)
|
| 1044 |
+
else:
|
| 1045 |
+
kwargs["timeout"] = timeout
|
| 1046 |
+
|
| 1047 |
+
# Handle headers
|
| 1048 |
+
if headers is not None:
|
| 1049 |
+
kwargs["headers"] = headers
|
| 1050 |
+
|
| 1051 |
+
# Handle authentication
|
| 1052 |
+
if auth is not None:
|
| 1053 |
+
kwargs["auth"] = auth
|
| 1054 |
+
|
| 1055 |
+
return httpx.AsyncClient(**kwargs, verify=self.verify)
|
| 1056 |
|
| 1057 |
class MCPClientRemote(MCPClientBase):
|
| 1058 |
|
|
|
|
| 1075 |
init_timeout = min(server.init_timeout or set["mcp_client_init_timeout"], 5)
|
| 1076 |
tool_timeout = min(server.tool_timeout or set["mcp_client_tool_timeout"], 10)
|
| 1077 |
|
| 1078 |
+
client_factory = CustomHTTPClientFactory(verify=server.verify)
|
| 1079 |
# Check if this is a streaming HTTP type
|
| 1080 |
if _is_streaming_http_type(server.type):
|
| 1081 |
# Use streamable HTTP client
|
|
|
|
| 1085 |
headers=server.headers,
|
| 1086 |
timeout=timedelta(seconds=init_timeout),
|
| 1087 |
sse_read_timeout=timedelta(seconds=tool_timeout),
|
| 1088 |
+
httpx_client_factory=client_factory,
|
| 1089 |
)
|
| 1090 |
)
|
| 1091 |
# streamablehttp_client returns (read_stream, write_stream, get_session_id_callback)
|
|
|
|
| 1103 |
headers=server.headers,
|
| 1104 |
timeout=init_timeout,
|
| 1105 |
sse_read_timeout=tool_timeout,
|
| 1106 |
+
httpx_client_factory=client_factory,
|
| 1107 |
)
|
| 1108 |
)
|
| 1109 |
return stdio_transport
|