Skip to content

feat: expose streamable HTTP session ID#893

Open
0xWeakSheep wants to merge 1 commit into
modelcontextprotocol:mainfrom
0xWeakSheep:issue-863-session-id
Open

feat: expose streamable HTTP session ID#893
0xWeakSheep wants to merge 1 commit into
modelcontextprotocol:mainfrom
0xWeakSheep:issue-863-session-id

Conversation

@0xWeakSheep

Copy link
Copy Markdown
Contributor

Closes #863.

This adds a way to read the negotiated Mcp-Session-Id from streamable HTTP clients.

The session ID is now available from:

  • StreamableHttpClientTransport::session_id()
  • StreamableHttpClientTransport::session_id_handle()
  • RunningService::session_id()

The value is set after initialize, updated if the client transparently re-initializes after an expired session, and cleared when the worker exits.

I also added test coverage that checks the exposed session ID matches the session stored by the server.

Checks run:

cargo +nightly fmt --all --check
git diff --check

@0xWeakSheep 0xWeakSheep requested a review from a team as a code owner June 6, 2026 15:58
@github-actions github-actions Bot added T-test Testing related changes T-core Core library changes T-transport Transport layer changes labels Jun 6, 2026

@DaleSeo DaleSeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, @0xWeakSheep! Sorry for the delay in reviewing this. I left some comments. I think we should fix the SemVer check failure before merging, unless the breaking change is intentional.

join_handle: Option<tokio::task::JoinHandle<Result<(), WorkerQuitReason<W::Error>>>>,
_drop_guard: tokio_util::sync::DropGuard,
ct: CancellationToken,
session_id_handle: Option<TransportSessionIdHandle>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The SemVer check flags this as a breaking change because it removes the auto traits. The simplest fix is probably to require TransportSessionIdProvider to preserve them.


/// Cloneable read-only handle for the negotiated streamable HTTP session ID.
#[derive(Debug, Clone, Default)]
pub struct StreamableHttpClientSession {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like an implementation detail.

Suggested change
pub struct StreamableHttpClientSession {
struct StreamableHttpClientSession {


/// Returns a handle for reading the current transport session ID, when the
/// transport protocol has one.
fn session_id_handle(&self) -> Option<TransportSessionIdHandle> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Most of the existing handle names in this project refer to task or runtime handles. How about calling it session_id_observer() or session_id_provider() instead so that the API can communicate that this value is read-only more clearly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-core Core library changes T-test Testing related changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose negotiated Mcp-Session-Id on StreamableHttpClientTransport / RunningService

2 participants