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
14 changes: 14 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,12 @@ async def sse_client(
):
"""Client transport for SSE.

.. deprecated::
sse_client is deprecated. Prefer to use
:func:`streamablehttp_client` where possible instead.
Note that because some servers still use SSE, clients may need
to support both transports during the migration period.

`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 +58,13 @@ async def sse_client(
auth: Optional HTTPX authentication handler.
on_session_created: Optional callback invoked with the session ID when received.
"""
warnings.warn(
"sse_client is deprecated. Prefer to use streamablehttp_client where possible "
"instead. Note that because some servers still use SSE, clients may need to "
"support both transports during the migration period.",
DeprecationWarning,
stacklevel=2,
)
read_stream: MemoryObjectReceiveStream[SessionMessage | Exception]
read_stream_writer: MemoryObjectSendStream[SessionMessage | Exception]

Expand Down
30 changes: 28 additions & 2 deletions src/mcp/server/mcpserver/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import inspect
import json
import re
import warnings
from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence
from contextlib import AbstractAsyncContextManager, asynccontextmanager
from typing import Any, Generic, Literal, TypeVar, overload
Expand Down Expand Up @@ -286,6 +287,11 @@ def run(
case "stdio":
anyio.run(self.run_stdio_async)
case "sse": # pragma: no cover
warnings.warn(
'transport="sse" is deprecated. Use transport="streamable-http" instead.',
DeprecationWarning,
stacklevel=2,
)
anyio.run(lambda: self.run_sse_async(**kwargs))
case "streamable-http": # pragma: no cover
anyio.run(lambda: self.run_streamable_http_async(**kwargs))
Expand Down Expand Up @@ -854,7 +860,17 @@ async def run_sse_async( # pragma: no cover
message_path: str = "/messages/",
transport_security: TransportSecuritySettings | None = None,
) -> None:
"""Run the server using SSE transport."""
"""Run the server using SSE transport.

.. deprecated::
SSE transport is deprecated. Prefer to use
:meth:`run_streamable_http_async` instead.
"""
warnings.warn(
"run_sse_async is deprecated. Use run_streamable_http_async instead.",
DeprecationWarning,
stacklevel=2,
)
import uvicorn

starlette_app = self.sse_app(
Expand Down Expand Up @@ -915,7 +931,17 @@ def sse_app(
transport_security: TransportSecuritySettings | None = None,
host: str = "127.0.0.1",
) -> Starlette:
"""Return an instance of the SSE server app."""
"""Return an instance of the SSE server app.

.. deprecated::
SSE transport is deprecated. Prefer to use
:meth:`streamable_http_app` instead.
"""
warnings.warn(
"sse_app is deprecated. Use streamable_http_app instead.",
DeprecationWarning,
stacklevel=2,
)
# Auto-enable DNS rebinding protection for localhost (IPv4 and IPv6)
if transport_security is None and host in ("127.0.0.1", "localhost", "::1"):
transport_security = TransportSecuritySettings(
Expand Down
28 changes: 26 additions & 2 deletions src/mcp/server/sse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
"""SSE Server Transport Module
"""SSE Server Transport Module (Deprecated)

.. deprecated::
The HTTP+SSE transport was replaced by Streamable HTTP in the
`2025-03-26 <https://modelcontextprotocol.io/specification/2025-03-26/changelog>`_
protocol revision. Use :class:`mcp.server.streamable_http.StreamableHTTPServerTransport`
instead. SSE is retained for backwards compatibility with older clients.

This module implements a Server-Sent Events (SSE) transport layer for MCP servers.

Expand Down Expand Up @@ -37,6 +43,7 @@ async def handle_sse(request):
"""

import logging
import warnings
from contextlib import asynccontextmanager
from typing import Any
from urllib.parse import quote
Expand All @@ -61,7 +68,15 @@ async def handle_sse(request):


class SseServerTransport:
"""SSE server transport for MCP. This class provides two ASGI applications,
"""SSE server transport for MCP.

.. deprecated::
``SseServerTransport`` is deprecated. Prefer to use
:class:`~mcp.server.streamable_http.StreamableHTTPServerTransport`
where possible instead. Note that because some clients still use SSE,
servers may need to support both transports during the migration period.

This class provides two ASGI applications,
suitable for use with a framework like Starlette and a server like Hypercorn:

1. connect_sse() is an ASGI application which receives incoming GET requests,
Expand Down Expand Up @@ -99,6 +114,15 @@ def __init__(self, endpoint: str, security_settings: TransportSecuritySettings |

super().__init__()

warnings.warn(
"SseServerTransport is deprecated. Prefer to use "
"StreamableHTTPServerTransport where possible instead. Note that because "
"some clients still use SSE, servers may need to support both transports "
"during the migration period.",
DeprecationWarning,
stacklevel=2,
)

# Validate that endpoint is a relative path and not a full URL
if "://" in endpoint or endpoint.startswith("//") or "?" in endpoint or "#" in endpoint:
raise ValueError(
Expand Down