Title: Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client · Issue #936 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client · Issue #936 · modelcontextprotocol/python-sdk
X Title: Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client · Issue #936 · modelcontextprotocol/python-sdk
Description: Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client Description In the modelcontextprotocol/python-sdk repository (version 1.9.3), the timeout and sse_read_timeout parameters in mcp/client/sse.py and m...
Open Graph Description: Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client Description In the modelcontextprotocol/python-sdk repository (version 1.9.3), the timeout and sse_read_timeo...
X Description: Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client Description In the modelcontextprotocol/python-sdk repository (version 1.9.3), the timeout and sse_read_timeo...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/issues/936
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client","articleBody":"# Inconsistent `timeout` and `sse_read_timeout` Types in `sse_client` and `streamablehttp_client`\n\n## Description\n\nIn the `modelcontextprotocol/python-sdk` repository (version 1.9.3), the `timeout` and `sse_read_timeout` parameters in `mcp/client/sse.py` and `mcp/client/streamable_http.py` have inconsistent types, causing confusion and runtime errors in downstream applications:\n\n- `mcp/client/sse.py` (`sse_client`):\n ```python\n @asynccontextmanager\n async def sse_client(\n url: str,\n headers: dict[str, Any] | None = None,\n timeout: float = 5,\n sse_read_timeout: float = 60 * 5,\n ...\n )\n ```\n - `timeout` and `sse_read_timeout` are typed as `float` (seconds).\n\n- `mcp/client/streamable_http.py` (`streamablehttp_client`):\n ```python\n @asynccontextmanager\n async def streamablehttp_client(\n url: str,\n headers: dict[str, Any] | None = None,\n timeout: timedelta = timedelta(seconds=30),\n sse_read_timeout: timedelta = timedelta(seconds=60 * 5),\n ...\n )\n ```\n - `timeout` and `sse_read_timeout` are typed as `timedelta`.\n\nThis inconsistency forces developers to handle different types for similar parameters across MCP transport implementations, leading to errors. For example, in the `openai-agents-python` project, passing a `float` timeout to `MCPServerStreamableHttp` (which uses `streamablehttp_client`) causes a `TaskGroup` exception:\n\n```\n2025-06-11 19:17:20,478 server.py:132 - mcp_client - [MainThread:5432] - ERROR - Error initializing MCP server: unhandled errors in a TaskGroup (1 sub-exception)\n```\n\nThe lack of clear error messages from `streamablehttp_client` (e.g., type mismatch) further complicates debugging.\n\n## Steps to Reproduce\n\n1. Configure an `MCPServerStreamableHttp` (from `openai-agents-python`) with a `float` timeout (e.g., `timeout=30`).\n2. Call `server.connect()`, which invokes `streamablehttp_client`.\n3. Observe a `TaskGroup` exception due to `timedelta` type mismatch.\n4. Compare with `MCPServerSse`, which accepts `float` without issues.\n\n## Expected Behavior\n\nBoth `sse_client` and `streamablehttp_client` should use consistent types for `timeout` and `sse_read_timeout` (preferably `float`, as it’s more intuitive for configuration files and aligns with `sse_client`). The functions should either handle type conversion internally or provide clear `TypeError` messages for invalid types.\n\n## Proposed Solution\n\n1. **Unify Parameter Types**:\n - Update `streamablehttp_client` to accept `timeout` and `sse_read_timeout` as `float` (seconds), matching `sse_client`.\n - Internally convert `float` to `timedelta` in `streamablehttp_client` if required by the underlying HTTP client (e.g., `httpx`).\n\n2. **Add Type Validation**:\n - In both `sse_client` and `streamablehttp_client`, validate that `timeout` and `sse_read_timeout` are `int` or `float`, raising a clear `TypeError` otherwise.\n\n3. **Update Documentation**:\n - Clearly document that `timeout` and `sse_read_timeout` are in seconds (`float`) for both functions.\n - Specify default values and any internal conversions.\n\n4. **Ensure Backward Compatibility**:\n - Allow `streamablehttp_client` to accept `timedelta` for a transition period, logging a deprecation warning and converting to `float` internally.\n\nExample implementation for `streamablehttp_client`:\n\n```python\nfrom datetime import timedelta\nfrom typing import Union\n\n@asynccontextmanager\nasync def streamablehttp_client(\n url: str,\n headers: dict[str, Any] | None = None,\n timeout: Union[float, timedelta] = 30.0, # Accept float, support timedelta temporarily\n sse_read_timeout: Union[float, timedelta] = 60 * 5.0,\n terminate_on_close: bool = True,\n httpx_client_factory: McpHttpClientFactory = create_mcp_http_client,\n auth: httpx.Auth | None = None,\n):\n if isinstance(timeout, timedelta):\n logger.warning(\"Using timedelta for timeout is deprecated; use float (seconds) instead\")\n timeout = timeout.total_seconds()\n if isinstance(sse_read_timeout, timedelta):\n logger.warning(\"Using timedelta for sse_read_timeout is deprecated; use float (seconds) instead\")\n sse_read_timeout = sse_read_timeout.total_seconds()\n \n if not isinstance(timeout, (int, float)):\n raise TypeError(f\"timeout must be float, got {type(timeout)}\")\n if not isinstance(sse_read_timeout, (int, float)):\n raise TypeError(f\"sse_read_timeout must be float, got {type(sse_read_timeout)}\")\n \n # Convert to timedelta for internal use if needed\n timeout_td = timedelta(seconds=float(timeout))\n sse_read_timeout_td = timedelta(seconds=float(sse_read_timeout))\n \n # Proceed with streamablehttp_client logic\n ...\n```\n\n## Additional Notes\n\n- This issue was discovered while using `MCPServerStreamableHttp` with a server at `http://localhost:3001/mcp` (confirmed reachable via `curl`).\n- The type inconsistency propagates to downstream projects like `openai-agents-python`, causing errors in `MCPServerStreamableHttp` initialization.\n- Suggest updating `MCPServerSseParams` and `MCPServerStreamableHttpParams` in `openai-agents-python` to align with the unified `float` type after this change.\n- Clearer error messages in `streamablehttp_client` (e.g., for type mismatches or HTTP errors) would greatly improve debugging.\n\n## Environment\n\n- Package version: `mcp` 1.9.3\n- Python version: [Specify your Python version, e.g., 3.10]\n- Operating system: [Specify your OS, e.g., macOS]\n\nPlease let me know if you need additional details or assistance to resolve this issue!","author":{"url":"https://github.com/yinglj","@type":"Person","name":"yinglj"},"datePublished":"2025-06-11T12:27:02.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/936/python-sdk/issues/936"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:901c8f39-1716-ac0b-26da-3e30cf53f53e |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | D6B8:E89C2:110F52D:17D47D8:6A61BB0D |
| html-safe-nonce | 03bdc4a48e9b86ea419e60e17727adbed99ca319989f622190f3efbdbdffce24 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENkI4OkU4OUMyOjExMEY1MkQ6MTdENDdEODo2QTYxQkIwRCIsInZpc2l0b3JfaWQiOiIxMzgxOTEyNTcxMTU1NjkyMzAxIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 60241b9b0c914d90252caa1233df7d5b6e56dc720718930bf85c4f14d71653ef |
| hovercard-subject-tag | issue:3136645224 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/modelcontextprotocol/python-sdk/936/issue_layout |
| twitter:image | https://opengraph.githubassets.com/f1cec7cff8902cf93d4a956c6788d272a2b3860a307988eb3677b79fc7b91a9f/modelcontextprotocol/python-sdk/issues/936 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/f1cec7cff8902cf93d4a956c6788d272a2b3860a307988eb3677b79fc7b91a9f/modelcontextprotocol/python-sdk/issues/936 |
| og:image:alt | Inconsistent timeout and sse_read_timeout Types in sse_client and streamablehttp_client Description In the modelcontextprotocol/python-sdk repository (version 1.9.3), the timeout and sse_read_timeo... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | yinglj |
| hostname | github.com |
| expected-hostname | github.com |
| None | 6f4633bcf01c1ad14b73fd07dd39ac31d61f3d3c2578ee08ec1792b7b351eeb9 |
| turbo-cache-control | no-preview |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | ac296ae7f21856f1f92adbad22f870b6fbb4b907 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width