Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ named `mcp.os.win32.utilities` (was `client.stdio.win32`).

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.

### SSE transport deprecated

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).

### Removed type aliases and classes

The following deprecated type aliases and classes have been removed from `mcp.types`:
Expand Down
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ filterwarnings = [
"error",
# pywin32 internal deprecation warning
"ignore:getargs.*The 'u' format is deprecated:DeprecationWarning",
# The SSE transport is intentionally deprecated (see sse_client / SseServerTransport). It is still
# exercised across the suite (directly and via the transport-parametrized interaction tests), so the
# SDK's own deprecation notice must not be promoted to an error here. tests/shared/test_sse.py asserts
# the warning is emitted.
"ignore:The SSE client transport is deprecated:DeprecationWarning",
"ignore:The SSE server transport is deprecated:DeprecationWarning",
]

[tool.markdown.lint]
Expand Down
12 changes: 12 additions & 0 deletions src/mcp/client/sse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import warnings
from collections.abc import Callable
from contextlib import asynccontextmanager
from typing import Any
Expand Down Expand Up @@ -39,6 +40,10 @@ async def sse_client(
):
"""Client transport for SSE.

Deprecated: this transport will be removed in a future version. The HTTP+SSE
transport was superseded by Streamable HTTP in protocol revision 2025-03-26;
use the streamable HTTP transport (`streamable_http_client`) instead.

`sse_read_timeout` determines how long (in seconds) the client will wait for a new
event before disconnecting. All other HTTP operations are controlled by `timeout`.

Expand All @@ -51,6 +56,13 @@ async def sse_client(
auth: Optional HTTPX authentication handler.
on_session_created: Optional callback invoked with the session ID when received.
"""
warnings.warn(
"The SSE client transport is deprecated and will be removed in a future version. The HTTP+SSE transport was"
" superseded by Streamable HTTP in protocol revision 2025-03-26; use the streamable HTTP transport"
" (`streamable_http_client`) instead.",
DeprecationWarning,
stacklevel=2,
)
logger.debug(f"Connecting to SSE endpoint: {remove_request_params(url)}")
async with httpx_client_factory(
headers=headers, auth=auth, timeout=httpx.Timeout(timeout, read=sse_read_timeout)
Expand Down
12 changes: 12 additions & 0 deletions src/mcp/server/sse.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ async def handle_sse(request):
"""

import logging
import warnings
from contextlib import asynccontextmanager
from typing import Any
from urllib.parse import quote
Expand Down Expand Up @@ -70,6 +71,10 @@ class SseServerTransport:
2. handle_post_message() is an ASGI application which receives incoming POST
requests, which should contain client messages that link to a
previously-established SSE session.

Deprecated: this transport will be removed in a future version. The HTTP+SSE
transport was superseded by Streamable HTTP in protocol revision 2025-03-26;
use the streamable HTTP transport instead.
"""

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

super().__init__()

Expand Down
18 changes: 18 additions & 0 deletions tests/shared/test_sse.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ def make_server_app() -> Starlette:
return make_app(Server(SERVER_NAME, on_read_resource=_handle_read_resource))


def test_sse_server_transport_emits_deprecation_warning() -> None:
"""Constructing SseServerTransport warns that the SSE server transport is deprecated."""
with pytest.warns(DeprecationWarning, match="The SSE server transport is deprecated"):
SseServerTransport(
"/messages/", security_settings=TransportSecuritySettings(enable_dns_rebinding_protection=False)
)


@pytest.mark.anyio
async def test_sse_client_emits_deprecation_warning() -> None:
"""Entering sse_client warns that the SSE client transport is deprecated."""
factory = in_process_client_factory(make_server_app())
with anyio.fail_after(5):
with pytest.warns(DeprecationWarning, match="The SSE client transport is deprecated"):
async with sse_client(f"{BASE_URL}/sse", httpx_client_factory=factory): # pragma: no branch
pass


@pytest.mark.anyio
async def test_raw_sse_connection() -> None:
"""The SSE GET responds 200 with an event-stream content type, announcing the session
Expand Down
Loading