mcp.client.http_transport

Undocumented in source.

Members

Classes

HttpClientTransport
class HttpClientTransport

A ClientTransport over the MCP Streamable HTTP transport.

LegacyFallbackException
class LegacyFallbackException

Internal signal that the modern single-endpoint POST returned an HTTP 400/404/405, the trigger for the legacy HTTP+SSE (2024-11-05) fallback. Surfaced to McpClient.connect so it can drive the fallback.

Functions

isLegacyFallbackStatus
bool isLegacyFallbackStatus(int status)

Whether an HTTP status from the initial modern POST should trigger the legacy HTTP+SSE (2024-11-05) backward-compatibility fallback. Per basic/transports §Backwards Compatibility, a client probing a single modern endpoint should fall back when the POST fails with 400 Bad Request, 404 Not Found, or 405 Method Not Allowed.

isModernRpcErrorCode
bool isModernRpcErrorCode(int code)

Whether a JSON-RPC error code carried in a 400/404/405 response body proves the peer speaks a *modern* MCP version (so the client should retry / correct rather than fall back to the legacy HTTP+SSE transport). Per draft basic/transports §Backward Compatibility the disambiguating modern errors a 4xx body may carry are UnsupportedProtocolVersionError (-32004), HeaderMismatch (-32001, header-validation failure), MissingRequiredClientCapabilityError (-32003), and — for a 404 to an unimplemented modern method — Method not found (-32601). These mirror the codes the SDK's own server emits via httpStatusForResponse.

modernErrorFromBody
bool modernErrorFromBody(string body, McpException err)

Inspect a 400/404/405 response body for a recognized modern JSON-RPC error before deciding whether to fall back to legacy HTTP+SSE. Per draft basic/transports §Backward Compatibility: "If the body contains a recognized modern JSON-RPC error, the server speaks a modern version of MCP — retry ... rather than falling back. If the body is empty or is not a recognized modern JSON-RPC error, fall back to initialize." Returns true and sets err to a typed McpException only when the body parses as a JSON-RPC error response whose code passes isModernRpcErrorCode; otherwise returns false (legacy fallback) and leaves err null. Never throws — a malformed/empty body is a legacy signal, not an error.

parseEndpointEvent
bool parseEndpointEvent(string sse, string uri)

Parse a legacy HTTP+SSE event stream looking for the first endpoint event, returning its data: payload (the message-POST URI) in uri. Returns false if no endpoint event is found in the supplied buffer. Handles CRLF and LF line endings and the optional single leading space after data:.

parseHttpEndpoint
HttpEndpoint parseHttpEndpoint(string url)

Parse scheme://host[:port][/path] into its components, defaulting the port to 443 for a TLS scheme (https/wss) and 80 otherwise. An absent path becomes "/". Tolerates a missing scheme (treated as non-TLS). See HttpEndpoint.

pinnedEndpointHost
string pinnedEndpointHost(HttpEndpoint ep)

Resolve, classify and PIN the host of an MCP client transport endpoint to a numeric address, returning the address to connectTCP to. The endpoint is user-configured (the URL the host passed to McpClient), so the allowUserConfigured SSRF policy is used: the address is resolved and pinned for TOCTOU stability, but loopback/private/link-local targets are permitted (a developer may legitimately point the client at localhost or an internal service). Only a fail-closed classification (unresolvable / malformed host) throws. The original ep.host is still used for the TLS SNI / Host header by openClientStream/buildHttpRequest; only the connect target changes. @safe.

resolveEndpointUri
string resolveEndpointUri(string baseUrl, string endpoint)

Resolve a legacy endpoint event URI (which may be absolute, root-relative, or document-relative) against the GET-SSE base URL, yielding the absolute URL to POST subsequent JSON-RPC messages to. An absolute URI is only accepted when it is same-origin with the base; a cross-origin absolute URI yields null so the legacy fallback fails closed rather than POSTing the bearer token off-origin.

sameOrigin
bool sameOrigin(string base, string candidate)

Whether candidate shares base's security origin: same scheme, host, and effective port (per-scheme default applied). The legacy POST endpoint a server supplies on the SSE stream is only trusted when it is same-origin, so the client never POSTs its bearer token to a server-named cross-origin URI. A scheme mismatch (e.g. an https base vs. an http candidate) is rejected too, so a downgrade cannot leak the credential in plaintext.

unbracketHost
string unbracketHost(string host)

Open a client byte stream to ep, wrapping the raw TCP connection in a vibe TLS tunnel when ep.tls is set (https/wss). Returns a ProxyStream so the five raw-TCP request paths share ONE TLS-handling site and treat the plaintext and TLS cases uniformly. The TLS context uses TLSContextKind.client with peer-certificate verification (checkPeer) and sets the SNI/peer name to ep.host, so the server certificate and hostname are validated; the underlying conn must outlive the returned stream (callers keep it in scope and close() it). On a plaintext endpoint the raw connection is returned unwrapped (still as a ProxyStream for a single static type). Remove the surrounding brackets from a bracketed IPv6 literal host ([::1] -> ::1), leaving any other host untouched. The TLS SNI/peer name and the SSRF/connect resolver both want the bare address, while the Host header keeps the brackets.

Structs

HttpEndpoint
struct HttpEndpoint

The parsed components of an MCP endpoint URL, shared by every raw-TCP request path so host/port/scheme parsing lives in exactly one place. tls is true for an https:///wss:// scheme; port defaults to the scheme's well-known port (443 when tls, else 80) when the URL omits it, so a TLS URL can never be silently treated as plaintext on port 80.