Remove the unsupported WebSocket transport#2785
Conversation
WebSocket was never part of the MCP specification. Delete the client and server transports (mcp.client.websocket, mcp.server.websocket), the ws optional-dependency extra, the websockets filterwarnings, and the transport's tests. tests/test_helpers.py goes too: the WebSocket test was the last remaining user of run_uvicorn_in_thread after the other transport tests moved in process. Documented in docs/migration.md; use streamable HTTP instead.
There was a problem hiding this comment.
LGTM — clean, complete removal of the unsupported WebSocket transport; I verified no dangling references remain anywhere in the repo (src, tests, examples, docs, CI).
Extended reasoning...
Overview
This PR is a pure deletion: it removes src/mcp/client/websocket.py, src/mcp/server/websocket.py, the ws optional-dependency extra, the WebSocket smoke test (tests/shared/test_ws.py), the now-orphaned tests/test_helpers.py (run_uvicorn_in_thread), the two websockets-related filterwarnings ignores in pyproject.toml, and regenerates uv.lock so the websockets package drops out of the resolution. A migration-guide entry is added under Breaking Changes pointing users to the streamable HTTP transport.
Verification
I grepped the entire repository (src, tests, examples, docs, README, .github workflows, scripts, mkdocs config) for any remaining references to websocket_client, websocket_server, mcp[ws], websockets, or run_uvicorn_in_thread — nothing dangling remains. The only surviving mentions are the intentional migration-guide entry and the standard ASGI {"type": "websocket"} scope literal in tests/server/test_sse_security.py, which the PR description correctly explains is unrelated to the removed transport.
Security risks
None. This change only deletes code and a dependency; removing the unmaintained websockets dependency slightly reduces the attack/maintenance surface. No auth, crypto, or permission code is touched.
Level of scrutiny
While this is a breaking change to public API surface, the level of code-correctness scrutiny needed is low: it is a mechanical removal of an explicitly unsupported, non-spec transport, executed completely and documented in the migration guide. It is consistent with the established v2 breaking-change series visible in recent commits (e.g. the streamable HTTP and SSE transport test refactors and prior deprecation removals already in docs/migration.md), and the rationale (WebSocket was never part of the MCP specification) is stated clearly in both the PR description and the migration guide.
Other factors
The bug-hunting system found no issues. The author reports the full test suite passes at 100% coverage with ruff and pyright clean, and the deleted test helper had no remaining callers after #2764/#2765/#2767. There are no outstanding reviewer comments on the PR.
Removes the WebSocket transport from the v2 SDK:
mcp.client.websocket.websocket_client,mcp.server.websocket.websocket_server, thewsoptional-dependency extra, and the transport's tests.Motivation and Context
WebSocket has never been part of the MCP specification, and the SDK transport was unsupported. v2 is the opportunity to drop it outright rather than carry it forward. Users should use the streamable HTTP transport instead.
tests/test_helpers.py(run_uvicorn_in_thread) is deleted as well: the WebSocket test was its last remaining caller after #2764/#2765/#2767 moved the other transport tests in process.How Has This Been Tested?
Full test suite passes locally at 100% coverage (
./scripts/test, includingstrict-no-cover); ruff and pyright are clean.uv.lockregenerated — thewebsocketspackage drops out of the resolution entirely.Breaking Changes
Yes — the transport modules and the
mcp[ws]extra no longer exist. Documented indocs/migration.mdunder Breaking Changes, grouped with the other transport changes.Types of changes
Checklist
Additional context
The
{"type": "websocket"}literal remaining intests/server/test_sse_security.pyis intentional: it is a standard ASGI scope type used to verifyconnect_sserejects non-HTTP scopes, unrelated to the removed transport. The twowebsocketsfilterwarningsignores inpyproject.tomlare also removed since nothing imports the package anymore.AI Disclaimer