Skip to content

Commit 87e40ac

Browse files
agaonkerclaude
andcommitted
Deprecate the SSE transport
HTTP+SSE was superseded by Streamable HTTP in protocol revision 2025-03-26, and the spec now documents it only for backwards compatibility. Emit a DeprecationWarning from both SSE transport primitives — `sse_client` (client) and `SseServerTransport` (server) — and note the deprecation in their docstrings. The high-level `MCPServer.sse_app()` / `run(transport="sse")` build on `SseServerTransport`, so they surface the warning too. Unlike the WebSocket deprecation, SSE is used internally (the high-level server app, `ClientSessionGroup`, the `python -m mcp.client` CLI) and across the transport-parametrized interaction test suite. A `typing_extensions.deprecated` decorator would therefore force a `# pyright: ignore[reportDeprecated]` at every internal call site, which AGENTS.md discourages. A plain `warnings.warn` gives the same runtime signal with no static-analysis fallout. `filterwarnings = ["error"]` would otherwise promote the SDK's own deprecation notice to a test error wherever SSE is exercised, so add two scoped `ignore` entries (mirroring the existing pywin32 one) and assert the warnings are emitted in tests/shared/test_sse.py. Closes #2278 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent cf110e3 commit 87e40ac

5 files changed

Lines changed: 52 additions & 0 deletions

File tree

docs/migration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ named `mcp.os.win32.utilities` (was `client.stdio.win32`).
149149

150150
The WebSocket transport has been removed: `mcp.client.websocket.websocket_client`, `mcp.server.websocket.websocket_server`, and the `ws` optional dependency extra (`mcp[ws]`) no longer exist. WebSocket was never part of the MCP specification. Use the streamable HTTP transport instead (`mcp.client.streamable_http.streamable_http_client` on the client, `streamable_http_app()` on the server), which supports bidirectional communication with server-to-client streaming over standard HTTP.
151151

152+
### SSE transport deprecated
153+
154+
The HTTP+SSE transport is now deprecated and emits a `DeprecationWarning`. The client transport `mcp.client.sse.sse_client` and the server transport `mcp.server.sse.SseServerTransport` (including the high-level `MCPServer.sse_app()` / `MCPServer.run(transport="sse")`, which build on it) are affected. HTTP+SSE was superseded by Streamable HTTP in protocol revision 2025-03-26 and the specification now documents it only for backwards compatibility. The transport still works and will be removed in a future version; migrate to the streamable HTTP transport (`streamable_http_client` on the client, `streamable_http_app()` on the server).
155+
152156
### Removed type aliases and classes
153157

154158
The following deprecated type aliases and classes have been removed from `mcp.types`:

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ filterwarnings = [
210210
"error",
211211
# pywin32 internal deprecation warning
212212
"ignore:getargs.*The 'u' format is deprecated:DeprecationWarning",
213+
# The SSE transport is intentionally deprecated (see sse_client / SseServerTransport). It is still
214+
# exercised across the suite (directly and via the transport-parametrized interaction tests), so the
215+
# SDK's own deprecation notice must not be promoted to an error here. tests/shared/test_sse.py asserts
216+
# the warning is emitted.
217+
"ignore:The SSE client transport is deprecated:DeprecationWarning",
218+
"ignore:The SSE server transport is deprecated:DeprecationWarning",
213219
]
214220

215221
[tool.markdown.lint]

src/mcp/client/sse.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
import warnings
23
from collections.abc import Callable
34
from contextlib import asynccontextmanager
45
from typing import Any
@@ -39,6 +40,10 @@ async def sse_client(
3940
):
4041
"""Client transport for SSE.
4142
43+
Deprecated: this transport will be removed in a future version. The HTTP+SSE
44+
transport was superseded by Streamable HTTP in protocol revision 2025-03-26;
45+
use the streamable HTTP transport (`streamable_http_client`) instead.
46+
4247
`sse_read_timeout` determines how long (in seconds) the client will wait for a new
4348
event before disconnecting. All other HTTP operations are controlled by `timeout`.
4449
@@ -51,6 +56,13 @@ async def sse_client(
5156
auth: Optional HTTPX authentication handler.
5257
on_session_created: Optional callback invoked with the session ID when received.
5358
"""
59+
warnings.warn(
60+
"The SSE client transport is deprecated and will be removed in a future version. The HTTP+SSE transport was"
61+
" superseded by Streamable HTTP in protocol revision 2025-03-26; use the streamable HTTP transport"
62+
" (`streamable_http_client`) instead.",
63+
DeprecationWarning,
64+
stacklevel=2,
65+
)
5466
logger.debug(f"Connecting to SSE endpoint: {remove_request_params(url)}")
5567
async with httpx_client_factory(
5668
headers=headers, auth=auth, timeout=httpx.Timeout(timeout, read=sse_read_timeout)

src/mcp/server/sse.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ async def handle_sse(request):
3737
"""
3838

3939
import logging
40+
import warnings
4041
from contextlib import asynccontextmanager
4142
from typing import Any
4243
from urllib.parse import quote
@@ -70,6 +71,10 @@ class SseServerTransport:
7071
2. handle_post_message() is an ASGI application which receives incoming POST
7172
requests, which should contain client messages that link to a
7273
previously-established SSE session.
74+
75+
Deprecated: this transport will be removed in a future version. The HTTP+SSE
76+
transport was superseded by Streamable HTTP in protocol revision 2025-03-26;
77+
use the streamable HTTP transport instead.
7378
"""
7479

7580
_endpoint: str
@@ -100,6 +105,13 @@ def __init__(self, endpoint: str, security_settings: TransportSecuritySettings |
100105
Raises:
101106
ValueError: If the endpoint is a full URL instead of a relative path
102107
"""
108+
warnings.warn(
109+
"The SSE server transport is deprecated and will be removed in a future version. The HTTP+SSE transport"
110+
" was superseded by Streamable HTTP in protocol revision 2025-03-26; use the streamable HTTP transport"
111+
" instead.",
112+
DeprecationWarning,
113+
stacklevel=2,
114+
)
103115

104116
super().__init__()
105117

tests/shared/test_sse.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,24 @@ def make_server_app() -> Starlette:
108108
return make_app(Server(SERVER_NAME, on_read_resource=_handle_read_resource))
109109

110110

111+
def test_sse_server_transport_emits_deprecation_warning() -> None:
112+
"""Constructing SseServerTransport warns that the SSE server transport is deprecated."""
113+
with pytest.warns(DeprecationWarning, match="The SSE server transport is deprecated"):
114+
SseServerTransport(
115+
"/messages/", security_settings=TransportSecuritySettings(enable_dns_rebinding_protection=False)
116+
)
117+
118+
119+
@pytest.mark.anyio
120+
async def test_sse_client_emits_deprecation_warning() -> None:
121+
"""Entering sse_client warns that the SSE client transport is deprecated."""
122+
factory = in_process_client_factory(make_server_app())
123+
with anyio.fail_after(5):
124+
with pytest.warns(DeprecationWarning, match="The SSE client transport is deprecated"):
125+
async with sse_client(f"{BASE_URL}/sse", httpx_client_factory=factory): # pragma: no branch
126+
pass
127+
128+
111129
@pytest.mark.anyio
112130
async def test_raw_sse_connection() -> None:
113131
"""The SSE GET responds 200 with an event-stream content type, announcing the session

0 commit comments

Comments
 (0)