Releases: modelcontextprotocol/python-sdk
Release list
v2.2.0
pip install -U mcp. Docs: https://py.sdk.modelcontextprotocol.io/
A few defaults changed in this release. If you run a server or client on 2.x, skim these first:
Behaviour changes
HTTP client redirects are only followed within the endpoint's origin (#3397)
Client("https://..."),streamable_http_clientandsse_clientfollow a redirect only if it stays on the same scheme, host and port (or upgradeshttptohttpson the same host).- A redirect anywhere else is not followed: the call fails with
MCPErrorand the session stays usable (an SSE connect fails withhttpx2.HTTPStatusError). If that other URL is the server you meant, use it as the endpoint URL. - The
follow_redirectssetting on anhttpx2.AsyncClientyou pass in is no longer used for MCP requests, so you don't need it for the trailing-slash redirect any more. - The OAuth providers apply the same rule to their own requests.
Idle Streamable HTTP sessions now expire (legacy <=2025-11-25 spec( (#3395)
- A stateful session with nothing in flight for 30 minutes is closed. The client's next request gets a 404 and it has to initialize again.
- Clients that keep the GET stream open (the SDK's
Clientdoes) are not affected. Neither are stateless servers or 2026-07-28 connections. - A server also holds at most 10 000 sessions at once; beyond that, new sessions get a 503.
- To turn either off:
mcp.run(transport="streamable-http", session_idle_timeout=None, max_sessions=None)(also onstreamable_http_app()andrun_streamable_http_async()).
The OAuth client checks the authorization server's issuer on the legacy path too (#3398)
- For servers without protected resource metadata, authorization server metadata whose
issuerisn't the server's own origin is now rejected withOAuthFlowError: Authorization server metadata issuer mismatch. The protected-resource-metadata path has done this since 2.0. - A 403 that isn't an
insufficient_scopechallenge is returned to the caller instead of retried. - If protected resource metadata can't be fetched because of a 5xx/429, the flow now stops instead of falling back to the legacy endpoints.
Two new MCPDeprecationWarnings (#3435, #3447)
ClientCredentialsOAuthProvider/PrivateKeyJWTOAuthProviderwithoutissuer=. Pass your authorization server's issuer URL; 3.0 will require it.AuthSettingswithresource_server_urlset butvalidate_token_resourceunset. Set it toTrueorFalse; 3.0 defaults it toTrue.- Both keep working as before in 2.x; this mostly matters if your tests turn warnings into errors.
New
AuthSettings.validate_token_resource: only accept tokens yourTokenVerifierreports as issued for this server (#3447).issuer=onClientCredentialsOAuthProviderandPrivateKeyJWTOAuthProvider(#3398).session_idle_timeout=andmax_sessions=on the Streamable HTTP server entry points (#3395).
Fixes
- A client
DELETEfrees its session immediately, and a refused opening request no longer leaves a session behind (#2455, #3228, #3300). $refs in a tool'soutputSchemaresolve within that schema only; an unresolvable one surfaces asRuntimeError: Invalid schema for tool ...(#3394).
Known gaps
The tasks extension (SEP-2663), DPoP (SEP-1932) and the jwt-bearer grant are not implemented yet; https://github.com/modelcontextprotocol/python-sdk/blob/main/ROADMAP.md tracks them.
What's Changed
- Gate draft PRs too and rewrite the auto-close comment by @maxisbey in #3378
- Resolve tool output-schema references within the schema document only by @maxisbey in #3394
- Expire idle Streamable HTTP sessions by default and cap concurrent sessions by @maxisbey in #3395
- Validate the authorization server metadata issuer on every discovery path by @maxisbey in #3398
- Deprecate constructing the pre-provisioned OAuth clients without an issuer by @maxisbey in #3435
- Exercise the SEP-2575 stateless probes and SEP-2243 resource/prompt headers in the conformance fixtures by @maxisbey in #3442
- Bump the github-actions group with 6 updates by @dependabot[bot] in #3424
- Move the docs-preview workflow scripts out of the YAML into .github/scripts by @maxisbey in #3446
- Skip automatic docs previews for fork PRs and drop the setup-uv retry steps by @maxisbey in #3445
- Follow redirects only within the MCP endpoint's origin by @maxisbey in #3397
- Bump pymdown-extensions from 11.0 to 11.0.1 by @dependabot[bot] in #3285
- Bump the locked versions of eight dev and test dependencies by @maxisbey in #3449
- Keep following a relative redirect when the endpoint URL carries userinfo by @maxisbey in #3450
- Add AuthSettings.validate_token_resource to check a bearer token's resource by @maxisbey in #3447
- docs: stop presenting the in-memory client as the way to connect by @maxisbey in #3443
- docs: ask for AI disclosure on comments too by @maxisbey in #3459
- docs: refresh translations, and translate pages in parallel by @maxisbey in #3458
- Replace RootModel wrappers with type aliases and TypeAdapter validation by @Kludex in #3470
Full Changelog: v2.1.1...v2.2.0
v1.30.0
Maintenance release of the 1.x line. 2.x is the current line; 1.x docs are at https://py.sdk.modelcontextprotocol.io/v1/.
A few defaults changed in this release. If you run a server or client on 1.x, skim these first:
Behaviour changes
HTTP client redirects are only followed within the endpoint's origin (#3448)
streamable_http_clientandsse_clientfollow a redirect only if it stays on the same scheme, host and port (or upgradeshttptohttpson the same host).- A redirect anywhere else now fails the request with
httpx.HTTPStatusError. If that other URL is the server you meant, use it as the endpoint URL. - The
follow_redirectssetting on anhttpx.AsyncClientyou pass in is no longer used for MCP requests, so you don't need it for the trailing-slash redirect any more. OAuthClientProviderapplies the same rule to its own requests.
Idle Streamable HTTP sessions now expire (#3426)
- A stateful session with nothing in flight for 30 minutes is closed. The client's next request gets a 404 and it has to initialize again.
- Clients that keep the GET stream open (the SDK's client does) are not affected.
- A server also holds at most 10 000 sessions at once; beyond that, new sessions get a 503.
- To turn either off:
FastMCP(..., session_idle_timeout=None, max_sessions=None).
The OAuth client checks the authorization server's issuer (#3431)
- Authorization server metadata whose
issuerdoesn't match the server it was fetched for is now rejected withOAuthFlowError: Authorization server metadata issuer mismatch. - Client registrations are now remembered per issuer; if the server later points at a different authorization server, the client registers again.
- If protected resource metadata can't be fetched because of a 5xx/429, the flow now stops instead of falling back to the legacy endpoints.
Two new DeprecationWarnings (#3431, #3451)
ClientCredentialsOAuthProvider/PrivateKeyJWTOAuthProviderwithoutissuer=. Pass your authorization server's issuer URL.AuthSettingswithresource_server_urlset butvalidate_token_resourceunset. Set it toTrueorFalse.- Both keep working as before in 1.x; this mostly matters if your tests turn warnings into errors.
New
AuthSettings.validate_token_resource: only accept tokens yourTokenVerifierreports as issued for this server (#3451).issuer=onClientCredentialsOAuthProviderandPrivateKeyJWTOAuthProvider(#3431).session_idle_timeout=andmax_sessions=onFastMCP(#3426).
What's Changed
- [v1.x] Resolve tool output-schema references within the schema document only by @maxisbey in #3396
- [v1.x] Expire idle Streamable HTTP sessions by default and cap concurrent sessions by @maxisbey in #3426
- [v1.x] Validate the authorization server metadata issuer on every discovery path by @maxisbey in #3431
- [v1.x] Follow redirects only within the MCP endpoint's origin by @maxisbey in #3448
- [v1.x] Add AuthSettings.validate_token_resource to check a bearer token's resource by @maxisbey in #3451
Full Changelog: v1.29.1...v1.30.0
v2.0.1
One off backport of the FastMCP import warning for 2.0.x, this is due to a lot of people running into this error and making issues on other repos about it. Ideally either pin mcp<2 or upgrade to 2.
What's Changed
Full Changelog: v2.0.0...v2.0.1
v2.1.1
v2.1.0
Highlights
ClientacceptsStdioServerParametersdirectly:Client(StdioServerParameters(command="uv", args=["run", "server.py"]))(#3321).- Prompt messages accept
ImageandAudio, prompt functions may return bare content blocks, andMessage/UserMessage/AssistantMessageare exported frommcp.server.mcpserver(#3320). - The 4 MiB request body limit now also covers the SSE transport and the OAuth endpoints;
SseServerTransportandMCPServer.sse_app()takemax_request_body_size, and the SSE message endpoint answers 405 to non-POST requests (#3336).
Behaviour changes to be aware of
- Handler exceptions (#3314): an unexpected exception from a tool, resource or prompt handler is logged once at ERROR with its traceback, and the client now sees only
Error executing tool <name>(or the resource/prompt equivalent) rather than the exception text. RaiseToolError/ResourceErrorwhen the message is meant for the model; those still reach the client and are logged at INFO without a traceback. - Content-block return annotations (#3320): a tool annotated to return
TextContent,EmbeddedResource,Image,Audio, or lists/unions of them no longer advertisesoutputSchemaor returnsstructuredContent; itscontentis unchanged. Passstructured_output=Trueto keep the previous shape.
Fixes
- TypedDict tool results:
NotRequiredkeys are omitted instead of serialized asnull, and registration no longer fails on Python 3.10 (#3224, #3227); recursive return types get an object-rootedoutputSchemathat pre-2026 clients accept (#3337). - 2026-07-28 over HTTP: a POSTed notification such as
notifications/cancelledis acknowledged with 202 instead of rejected with 400 (#3324). - Pre-2026 sessions ignore cache-hint fields from later revisions instead of failing
list_tools()(#3223), and accept boolean sub-schemas in tool schemaproperties(#3353). mcp installreads and preserves a Claude Desktop config containing non-ASCII text on any Windows code page (#3296).
What's Changed
- Retire wording tied to pre-2.0 milestones by @maxisbey in #3211
- Describe the maintenance line without hardcoding 1.28 by @maxisbey in #3212
- Ask which release line a bug report is on by @maxisbey in #3213
- Link the released 2026-07-28 spec and point migrators at /v1/ by @maxisbey in #3214
- Bump conformance harness to 0.2.0-alpha.11 by @maxisbey in #3282
- Read UTF-8 test fixtures with explicit encoding by @ShuQingDollarVoyager in #3245
- Pin each conformance leg to a spec-revision wire by @maxisbey in #3304
- docs: publish translated docs in twelve languages and the tool that maintains them by @maxisbey in #3280
- Pin text I/O to UTF-8 and fail CI on locale-dependent reads/writes by @maxisbey in #3296
- docs: lead the README client example with a URL, not the server object by @maxisbey in #3315
- Publish versioning, roadmap, and dependency policies for v2 by @maxisbey in #3215
- Drop later-revision cache-hint fields on pre-2026 sessions by @maxisbey in #3223
- Stop framing breaking changes as a workflow in AGENTS.md by @maxisbey in #3286
- MCPServer: content-block returns are unstructured, prompt messages take Image/Audio by @maxisbey in #3320
- Let Client take StdioServerParameters directly by @maxisbey in #3321
- Gate external PRs on an assigned, linked issue by @maxisbey in #3291
- docs: cover the remaining Tier 1 audit items by @maxisbey in #3325
- Acknowledge notification POSTs with 202 on the 2026-07-28 HTTP entry by @maxisbey in #3326
- Shorten stdio test comments by @Kludex in #3329
- Hand TypedDict tool results to pydantic natively by @maxisbey in #3331
- Apply the request body limit to the SSE and OAuth endpoints by @maxisbey in #3336
- Accept boolean sub-schemas in 2025-11-25 tool schema properties by @pja-ant in #3354
- Log MCPServer handler exceptions by kind and keep crash details off the wire by @maxisbey in #3314
- Give recursive tool return types an object-rooted output schema by @maxisbey in #3376
- docs: refresh translations for recent English changes by @maxisbey in #3379
- Build releases with the pinned hatchling and a publish action that accepts Metadata 2.5 by @maxisbey in #3380
New Contributors
- @ShuQingDollarVoyager made their first contribution in #3245
Full Changelog: v2.0.0...v2.1.0
v1.29.1
What's Changed
- [v1.x] Complete the FastMCP Settings model at import time by @maxisbey in #3352
- [v1.x] Apply the request body limit to the SSE and OAuth endpoints by @maxisbey in #3344
- [v1.x] Give recursive tool return types an object-rooted output schema by @maxisbey in #3377
Full Changelog: v1.29.0...v1.29.1
v2.0.0
MCP Python SDK v2 Stable Release
This is v2.0.0, the stable v2 release of the MCP Python SDK. It supports the 2026-07-28 revision of the Model Context Protocol and serves every earlier revision from the same server. pip install mcp now installs 2.x.
pip install "mcp[cli]"
# or
uv add "mcp[cli]"Documentation Rewrite
The documentation has the full tutorial and API reference. Coming from v1? What's new in v2 is the tour of what changed and why, and the migration guide lists every breaking change with before-and-after code.
V1 Maintenance mode
v1.x is in maintenance mode and will only receive security fixes from now on The 1.x line lives on the v1.x branch, continues to receive critical bug fixes and security patches, and is documented at https://py.sdk.modelcontextprotocol.io/v1/. If your project is not ready to migrate, keep a <2 upper bound on your requirement (for example mcp>=1.28,<2).
Highlights
One SDK, both protocol eras
v2 speaks the 2026-07-28 revision (stateless requests with no handshake, server/discover, subscriptions/listen, multi-round-trip requests) and still serves every 2025-era client from the same MCPServer, over Streamable HTTP and stdio, with nothing to configure. Client(target) negotiates the version automatically.
FastMCP is now MCPServer, and there is a first-class Client
The decorator API is unchanged; the low-level Server is rebuilt around a shared dispatcher engine, and one Client object replaces v1's transport-plus-ClientSession-plus-initialize() layering. It connects to a URL, a stdio subprocess, a custom transport, or straight to a server object in memory for tests.
Multi-round-trip requests and resolver dependency injection
At 2026-07-28 the server can no longer call the client, so tools return the question instead. A Resolve(fn) parameter is filled by your function invisibly to the model and can put a question to the user; one tool body serves both eras.
Extension APIs, OpenTelemetry, and a standalone types package
Servers and clients compose protocol extensions through pluggable extension APIs (MCP Apps built in); OpenTelemetry tracing ships on by default; every protocol type is its own package, mcp-types (imported as mcp_types), published in lock-step with mcp.
Hardened stdio and auth
stdio servers keep handler subprocesses and stray prints off the wire, and stdout is diverted to stderr while serving. OAuth adds RFC 9207 issuer validation, the SEP-990 identity-assertion flow, and the client-credentials extension.
Coming from a v2 pre-release
Since the last release candidate: the per-version wire packages are private (mcp_types._v*), mcp.types is a permanent alias for mcp_types, the auth registration request model is split from the registered-client record, cancelled requests are no longer answered, and log notifications are gated on the per-request log-level opt-in at 2026-07-28. Since the betas: Client(cache=False) is now cache=None with CacheConfig() the default; Context.client_id, RFC7523OAuthClientProvider, and OAuthClientProvider(timeout=) are removed; the client-credentials providers take scope=; message_handler receives notifications and exceptions only; FileResource(is_binary=) becomes encoding; MCP_* env vars are gone with pydantic-settings; Streamable HTTP servers reject bodies over 4 MiB with HTTP 413. The migration guide covers all of it.
Known gaps
The tasks extension (SEP-2663) is not part of this release. On the client, the DPoP proof binding (SEP-1932) and the workload-identity jwt-bearer grant are not implemented; both are additive and can land in 2.x.
Feedback
Something rough, confusing, or broken? Open an issue or find us in #python-sdk-dev on the MCP Contributors Discord.
Full Changelog: v2.0.0rc1...v2.0.0
v1.29.0
What's Changed
- [v1.x] Route Context.report_progress() to the originating request stream by @maxisbey in #2994
- [v1.x] docs: publish llms.txt and markdown renditions of the docs by @maxisbey in #3029
- [v1.x] docs: pin mkdocs<2 by @maxisbey in #3074
- [v1.x] Add Streamable HTTP request body limits by @Kludex in #3101
- [v1.x] fix: reject trailing newline in tool-name validation by @maxisbey in #3086
- [v1.x] ci: pick the docs toolchain per worktree in build-docs.sh by @maxisbey in #3082
- [v1.x] Move the v1.x docs to /v1/ and mark v1.x as the maintenance line by @maxisbey in #3177
Full Changelog: v1.28.1...v1.29.0
v2.0.0rc1
First v2 release candidate. Pre-releases are opt-in only; pip install mcp still resolves to the stable 1.x line.
pip install mcp==2.0.0rc1
# or
uv add "mcp==2.0.0rc1"The documentation has the full tutorial and API reference, and the migration guide covers coming from v1. Stable v2 is planned for 2026-07-28 alongside the spec release - keep pinning an exact version until then.
Highlights
API cleanup ahead of stable (breaking for beta users)
The last pre-release pass over the public surface; every item has a migration guide entry.
Client(cache=False)is nowClient(cache=None):CacheConfig()is the default andNoneswitches the response cache off (#3164).Context.client_idis removed - read_metaviactx.request_context.meta, or the authenticated client viaget_access_token().client_id(#3167).RFC7523OAuthClientProviderandJWTParametersare removed - useClientCredentialsOAuthProvider,PrivateKeyJWTOAuthProvider, orIdentityAssertionOAuthProvider(#3169).- The client-credentials providers take
scope=, notscopes=(#3166). OAuthClientProvider(timeout=...)is removed; it never bounded anything (#3165).message_handlerreceivesServerNotification | Exceptiononly; the deadRequestResponderarm and themcp.shared.sessionmodule are gone (#3168).FileResource(is_binary=...)is replaced byencoding: str | None(#3171).MCP_*environment variables never configuredMCPServerand are no longer advertised;pydantic-settingsis dropped from the runtime dependencies (#3170).- Streamable HTTP servers reject request bodies over 4 MiB with HTTP 413; raise
max_request_body_sizeif you accept larger messages (#3095).
Aligned with the final 2026-07-28 identity shape (#3143)
The request-side clientInfo _meta key is optional (the required pair is protocolVersion + clientCapabilities), and serverInfo moved out of the server/discover result body into every 2026-era result's _meta; client.server_info is now Implementation | None. This tracks spec change #3002 and fixes interop with servers that already omit body serverInfo.
The full 2026-07-28 revision over stdio (#3152)
A stdio (or in-memory) server now decides the protocol era from the client's opening request, so subscriptions/listen and every other 2026-07-28 feature serve over stdio, not only Streamable HTTP.
stdio servers keep handlers off the wire (#3117)
stdio_server() serves from private duplicates of stdin/stdout and points fd 0 at the null device and fd 1 at stderr while it runs, so a stray print() or a chatty child process can no longer corrupt the JSON-RPC stream. This fixes the classic print-corrupts-the-wire class (#409) and the Windows tool-call hang (#671).
Notes
- Tool results validated against an output schema are much faster: the JSON Schema validator is compiled once and cached (#3134).
- The tasks extension (SEP-2663) is not in this release, and will not be in v2.0.0.
- If you install under uv's
exclude-newercooldown:mcppinsmcp-typesto the exact same version, so exempt both packages -exclude-newer-package = { mcp = false, mcp-types = false }.
What's Changed
- Add Streamable HTTP request body limits by @Kludex in #3095
- docs: document Windows stdio subprocess stdin handling by @AndreKalberer in #3079
- docs: make API reference rendering independent of page order by @maxisbey in #3107
- Pin pymdown-extensions back to 11.0 by @maxisbey in #3106
- docs: load media examples from disk instead of inline base64 by @maxisbey in #3108
- Align with spec #3002: optional clientInfo, serverInfo in result _meta by @maxisbey in #3143
- Serve the 2026-07-28 protocol over stdio: decide the era from the opening request by @maxisbey in #3152
- Isolate the stdio server's stdin and stdout from handler subprocesses by @maxisbey in #3117
- Make CacheConfig() the Client cache default and None the off switch by @maxisbey in #3164
- Remove Context.client_id by @maxisbey in #3167
- Rename scopes= to scope= on the client-credentials OAuth providers by @maxisbey in #3166
- Correct stable v2 target date to 2026-07-28 by @maxisbey in #3105
- Remove the deprecated RFC7523OAuthClientProvider by @maxisbey in #3169
- Stop advertising MCP_* env vars for MCPServer settings; drop pydantic-settings by @maxisbey in #3170
- Remove the unused timeout parameter from OAuthClientProvider by @maxisbey in #3165
- Narrow message_handler's parameter to notifications and exceptions by @maxisbey in #3168
- Replace FileResource.is_binary with an encoding field by @maxisbey in #3171
- Cache compiled output-schema validators on ClientSession by @jlowin in #3134
- Lengthen the demo signing keys in the identity-assertion examples by @maxisbey in #3180
- Repin conformance harness to the published 0.2.0-alpha.10 by @maxisbey in #3184
- Point pre-release install pins at 2.0.0rc1 by @maxisbey in #3186
New Contributors
- @AndreKalberer made their first contribution in #3079
Full Changelog: v2.0.0b2...v2.0.0rc1
v2.0.0b2
Second v2 beta. Pre-releases are opt-in only; pip install mcp still resolves to the stable 1.x line.
pip install mcp==2.0.0b2
# or
uv add "mcp==2.0.0b2"The documentation has the full tutorial and API reference, and the migration guide covers coming from v1. Stable v2 is still targeted for 2026-07-28 alongside the spec release - keep pinning an exact version.
Highlights
httpx is replaced by httpx2 (#2972)
The SDK's HTTP stack now runs on httpx2 (>=2.5.0), the next-generation httpx fork with SSE support built in, replacing httpx + httpx-sse. Most code needs no changes; if you pass your own http_client into a transport, change the import to httpx2. Runtime behavior that changes:
- TLS verification uses the operating system trust store (via
truststore) instead of certifi's bundle.SSL_CERT_FILE/SSL_CERT_DIRare honored first. - Loggers are renamed:
httpx->httpx2,httpcore.*->httpcore2.*- update logging filters that match on those names. - SSE GET streams send
Accept: application/json, text/event-stream(previously exactlytext/event-stream).
Client-side subscriptions/listen (#3047)
The client half of subscriptions/listen (SEP-2575), promised in the b1 notes: one context manager, async for consumption, typed events.
async with client.listen(tools_list_changed=True, resource_subscriptions=["note://todo"]) as sub:
print(sub.honored) # the subset the server agreed to deliver
async for event in sub:
match event:
case ToolsListChanged():
tools = await client.list_tools()
case ResourceUpdated(uri=uri):
body = await client.read_resource(uri)Entering waits for the server's acknowledgment, so sub.honored is always populated and pre-ack failures raise instead of degrading silently.
Request cancellation works on the 2026 transports (#3046)
Cancelling or timing out a client request now actually stops it: over streamable HTTP the request's own POST/SSE stream is closed (the spec's cancellation signal), and over stdio the client sends notifications/cancelled. Callers can also supply the request id for a call - the seam the listen driver builds on.
Resolvers can sample and list roots (#3049)
Resolver dependency injection now covers all three multi-round-trip request kinds (SEP-2322): a dependency can return Sample(...) or ListRoots() in addition to Elicit(...), so a tool can ask the client's LLM or fetch its roots mid-call, on both protocol eras.
Notes
- Tool-name validation now rejects names with a trailing newline (#3076).
- The tasks extension is still in review and will ship in a later pre-release.
- If you install under uv's
exclude-newercooldown:mcppinsmcp-typesto the exact same version, so exempt both packages -exclude-newer-package = { mcp = false, mcp-types = false }.
What's Changed
- De-flake conformance CI: solo re-verification, spawn-storm reduction, result artifacts by @maxisbey in #3043
- Harden the dual-era stream loop's era-lock and rejection semantics by @maxisbey in #3040
- docs: restructure into topical sections and add the four most-asked-for pages by @maxisbey in #3044
- docs: add a "What's new in v2" page by @maxisbey in #3054
- docs: modernize the site theme by @maxisbey in #3057
- docs: restructure the migration guide around topical groups with a navigation layer by @maxisbey in #3058
- Make client-side cancellation work over the 2026 transports by @maxisbey in #3046
- Extend resolver DI to sampling and roots requests by @maxisbey in #3049
- Share one event loop per test module to stop Windows socketpair churn by @maxisbey in #3070
- docs: pin mkdocs<2 and silence the mkdocs-material advisory banner in CI by @maxisbey in #3072
- Add the client-side subscriptions/listen driver by @maxisbey in #3047
- Gate the test matrix and retry setup-uv's flaky manifest fetch by @maxisbey in #3080
- ci: pick the docs-preview toolchain from the PR checkout by @maxisbey in #3081
- docs: replace MkDocs with Zensical by @Kludex in #3073
- fix: reject trailing newline in tool-name validation by @Otis0408 in #3076
- Replace httpx and httpx-sse with httpx2 by @Kludex in #2972
New Contributors
- @Otis0408 made their first contribution in #3076
Full Changelog: v2.0.0b1...v2.0.0b2