Minor Changes
- #2901
433eb41Thanks @claude! - The HTTP client transports and the OAuth client helpers now follow a redirect only when it stays within the origin of the request (same scheme, host and port, or http to https on the same host with default ports) and keeps the method (a 307 or 308, or any redirect of a GET). Any other redirect is not followed. A transport then fails the request with an error that names the target; the session is kept and later messages still send. OAuth metadata discovery moves on to the next well-known URL, and any other OAuth request fails with an error that gives the status. Same-origin redirects that keep the method keep working on Node, up to five in a row, and no code changes are needed there. If your endpoint redirects to another origin, configure the transport with the URL it redirects to. ArequestInit.redirectof'error'or'manual'is passed to fetch as it is for the requests a transport sends to the server (POST, GET and DELETE of the Streamable HTTP transport, POST of the SSE transport); for its OAuth requests, and for any other value,requestInit.redirectis not consulted by default. Browsers do not expose the target of a redirect to a page, so there a redirected request fails instead of being followed. SettingredirectPolicy: 'follow'on a transport leaves its redirects to the fetch implementation, as before this change.
Patch Changes
-
#2599
5238fbaThanks @freya0926! - A server can now serve, and a client can now call,tasks/getandtasks/cancelof the Tasks extension (SEP-2663) on a 2026-07-28 connection, when the handler is registered and the request is sent with an explicit schema. Every other method that a protocol revision removed is still refused. If one server factory serves both eras and such a handler is meant for 2025-era clients only, register it only whenctx.era === 'legacy'. -
#2846
63c0fcaThanks @Sthreal! - Receiving a large message as a single SSE event over Streamable HTTP, such as a tool result of tens of megabytes, is now fast: a 50 MB result that took about 13 seconds arrives in under a second. The client now requireseventsource-parser3.0.8 or later.SSEClientTransportreads through theeventsourcepackage and gets the same speed-up once that also resolveseventsource-parser3.0.8 or later. -
#2908
633dd3eThanks @claude! - Thelicensefield of the package manifests is nowApache-2.0; theLICENSEfile shipped in each package carries the full terms, including the MIT text for earlier contributions. No code change. -
#2903
e765b3bThanks @claude! - WithversionNegotiationin'auto'or pin mode, aserver/discoverprobe answered with a 2xx that carries no usable reply (a body that
is not JSON underapplication/json, a bare204, a missing or unaccepted content type) still rejectsconnect()with
EraNegotiationFailed; an empty SSE stream or a202surfaces as the probe timeout instead. The message now says
the server answered with an unusable reply (...)instead of reading like a network failure. To connect to a 2025 server behind a front that
answers the probe this way, passconnect(transport, { prior: { kind: 'legacy' } })or usemode: 'legacy'. -
#2905
c0cd01aThanks @claude! -SSEClientTransportnow retries the SSE connection once afteronUnauthorized()resolves, as documented. If the retry is also answered with 401,start()rejects withSdkHttpError(ClientHttpAuthentication) instead of callingonUnauthorized()again. A 401 on a later reconnect of a stream that had opened still gets one refresh. -
Updated dependencies [
633dd3e]:- @modelcontextprotocol/core@2.3.0