Skip to content

Commit 1183962

Browse files
authored
fix serialization issue in streamablehttp mcp tools (#6721)
<!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> The current `StreamableHttpServerParams` has timedelta values that are not JSON serializable (config.dump_component.model_dump_json()). This make is unusable in UIs like AGS that expect configs to be serializable to json, ```python class StreamableHttpServerParams(BaseModel): """Parameters for connecting to an MCP server over Streamable HTTP.""" type: Literal["StreamableHttpServerParams"] = "StreamableHttpServerParams" url: str # The endpoint URL. headers: dict[str, Any] | None = None # Optional headers to include in requests. timeout: timedelta = timedelta(seconds=30) # HTTP timeout for regular operations. sse_read_timeout: timedelta = timedelta(seconds=60 * 5) # Timeout for SSE read operations. terminate_on_close: bool = True ``` This PR uses float for time outs and casts it to timedelta as needed. ```python class StreamableHttpServerParams(BaseModel): """Parameters for connecting to an MCP server over Streamable HTTP.""" type: Literal["StreamableHttpServerParams"] = "StreamableHttpServerParams" url: str # The endpoint URL. headers: dict[str, Any] | None = None # Optional headers to include in requests. timeout: float = 30.0 # HTTP timeout for regular operations in seconds. sse_read_timeout: float = 300.0 # Timeout for SSE read operations in seconds. terminate_on_close: bool = True ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed.
1 parent 9b8dc8d commit 1183962

File tree

3 files changed

+11
-8
lines changed

3 files changed

+11
-8
lines changed

python/packages/autogen-ext/src/autogen_ext/tools/mcp/_config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from datetime import timedelta
21
from typing import Any, Literal
32

43
from mcp import StdioServerParameters
@@ -32,8 +31,8 @@ class StreamableHttpServerParams(BaseModel):
3231

3332
url: str # The endpoint URL.
3433
headers: dict[str, Any] | None = None # Optional headers to include in requests.
35-
timeout: timedelta = timedelta(seconds=30) # HTTP timeout for regular operations.
36-
sse_read_timeout: timedelta = timedelta(seconds=60 * 5) # Timeout for SSE read operations.
34+
timeout: float = 30.0 # HTTP timeout for regular operations in seconds.
35+
sse_read_timeout: float = 300.0 # Timeout for SSE read operations in seconds.
3736
terminate_on_close: bool = True
3837

3938

python/packages/autogen-ext/src/autogen_ext/tools/mcp/_session.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ async def create_mcp_server_session(
3232
) as session:
3333
yield session
3434
elif isinstance(server_params, StreamableHttpServerParams):
35-
async with streamablehttp_client(**server_params.model_dump(exclude={"type"})) as (
35+
# Convert float seconds to timedelta for the streamablehttp_client
36+
params_dict = server_params.model_dump(exclude={"type"})
37+
params_dict["timeout"] = timedelta(seconds=server_params.timeout)
38+
params_dict["sse_read_timeout"] = timedelta(seconds=server_params.sse_read_timeout)
39+
40+
async with streamablehttp_client(**params_dict) as (
3641
read,
3742
write,
3843
session_id_callback, # type: ignore[assignment, unused-variable]
@@ -41,6 +46,6 @@ async def create_mcp_server_session(
4146
async with ClientSession(
4247
read_stream=read,
4348
write_stream=write,
44-
read_timeout_seconds=server_params.sse_read_timeout,
49+
read_timeout_seconds=timedelta(seconds=server_params.sse_read_timeout),
4550
) as session:
4651
yield session

python/packages/autogen-ext/src/autogen_ext/tools/mcp/_streamable_http.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ class StreamableHttpMcpToolAdapter(
4949
.. code-block:: python
5050
5151
import asyncio
52-
from datetime import timedelta
5352
from autogen_ext.models.openai import OpenAIChatCompletionClient
5453
from autogen_ext.tools.mcp import StreamableHttpMcpToolAdapter, StreamableHttpServerParams
5554
from autogen_agentchat.agents import AssistantAgent
@@ -62,8 +61,8 @@ async def main() -> None:
6261
server_params = StreamableHttpServerParams(
6362
url="https://api.example.com/mcp",
6463
headers={"Authorization": "Bearer your-api-key", "Content-Type": "application/json"},
65-
timeout=timedelta(seconds=30),
66-
sse_read_timeout=timedelta(seconds=60 * 5),
64+
timeout=30.0, # HTTP timeout in seconds
65+
sse_read_timeout=300.0, # SSE read timeout in seconds (5 minutes)
6766
terminate_on_close=True,
6867
)
6968

0 commit comments

Comments
 (0)