Skip to content

Send DELETE request when closing a Streamable HTTP session on the client #501

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

halter73
Copy link
Contributor

This updates StreamableHttpClientSessionTransport.DisposeAsyncto send a delete request.

  1. Clients that no longer need a particular session (e.g., because the user is leaving the client application) SHOULD send an HTTP DELETE to the MCP endpoint with the Mcp-Session-Id header, to explicitly terminate the session.
  • The server MAY respond to this request with HTTP 405 Method Not Allowed, indicating that the server does not allow clients to terminate sessions.

https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http

if (!string.IsNullOrEmpty(_mcpSessionId))
{
using var deleteRequest = new HttpRequestMessage(HttpMethod.Delete, _options.Endpoint);
CopyAdditionalHeaders(deleteRequest.Headers, _options.AdditionalHeaders, _mcpSessionId);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to self to include _mcpProtocolVersion here once #500 is merged.

CopyAdditionalHeaders(deleteRequest.Headers, _options.AdditionalHeaders, _mcpSessionId);

// Do not validate we get a successful status code, because server support for the DELETE request is optional
using var deleteResponse = await _httpClient.SendAsync(deleteRequest, CancellationToken.None).ConfigureAwait(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this fails, it looks like that failure will propagate (for things other than cancellation). Do we want to eat any failures?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also be:

Suggested change
using var deleteResponse = await _httpClient.SendAsync(deleteRequest, CancellationToken.None).ConfigureAwait(false);
(await _httpClient.SendAsync(deleteRequest, CancellationToken.None).ConfigureAwait(false)).Dispose();

Copy link
Contributor Author

@halter73 halter73 Jun 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on the fence about this. Would it be even better to make this fire-and-forget? We risk disposing the SocketsHttpHandler before the DELETE request completes, but maybe that's better than unnecessarily slowing down DisposeAsync.

In general, I do not like catching exceptions unless there is a clear reason we should. I've seen too many cases where overly broad catch blocks in teardown logic make it harder to diagnose errors related to graceful shutdown.

The flip side of this is that we might be disposing the client in reaction to some other sever-side error, and an error from the DELETE request could obscure that. And most people probably don't really care if the DELETE request succeeds or even that it gets sent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants