fix(transport): cancel pending modern HTTP requests - #1194
Draft
lucarlig wants to merge 1 commit into
Draft
Conversation
Signed-off-by: lucarlig <luca.carlig@ibm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Allow modern Streamable HTTP requests to be cancelled before their POST returns the first response event. The client worker stays responsive while request POSTs are in flight, and the same per-request cancellation token continues to own any returned SSE stream.
Motivation and Context
Fixes #1193.
RequestHandle::cancel()currently waits forever when a2026-07-28request POST is still waiting for its response stream. The worker awaits the POST inline, so it cannot process the cancellation that should close that same request.This is required by the modern MCP transport rules:
How Has This Been Tested?
The new integration test uses an RMCP client and server over a real Axum HTTP listener. Before the fix, it fails after five seconds because
RequestHandle::cancel()remains pending. With the fix, cancellation returns and the server'sRequestContext::ctfires.cargo +nightly fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --all-features— 783 passed, 24 ignoredBreaking Changes
None. This fixes modern Streamable HTTP cancellation behavior without changing the public API. Legacy lifecycle, session, and re-initialization paths are unchanged.
Types of changes
Checklist
Additional context
The implementation uses RMCP's existing Tokio
JoinSetandCancellationToken; it adds no dependency. A modern request's token is registered before its POST starts. Cancelling the request drops the pending HTTP future, and if the POST returns an SSE stream first, that same token controls the stream as before. Response-versus-cancellation races keep the existing behavior of ignoring a response after cancellation.Issues #857 and PR #967 added the matching server-side disconnect handling. This change makes RMCP's public client cancellation API trigger that path even before response headers or the first SSE event arrive.