Skip to content

StreamableHTTPTransport: SSE stream abort should notify via onclose (or new callback) #1762

@StephenHaney

Description

@StephenHaney

Human note: Cursor generated this report for me, since it helped me give perfect specifics, but it's all from me and human-edited.

The impact is that we can't actually tell if an agent is still there when using http-transport, since the SSE stream closing is hidden from our app-code, and agents do not send DELETE requests when they poof.


When a client opens a GET SSE stream and then disconnects (e.g. the agent process exits, network drops, etc.), the transport's internal stream.onAbort handler fires and cleans up #streamMapping, but the disconnection is never propagated to the onclose callback or any other external hook.

Current behavior

// Inside handleGetRequest — stream abort only cleans up internal state
stream.onAbort(() => {
this.#streamMapping.get(resolvedStreamId)?.cleanup();
});

onclose is only called inside close(), which is only triggered by an explicit DELETE request. In practice, MCP clients (Cursor, Claude Code, etc.) do not send DELETE when they disconnect — the SSE stream dropping is the only signal available.

Expected behavior:

When the standalone SSE stream (_GET_stream) aborts, the transport should notify the application. This could be:

  1. Calling onclose when the standalone SSE stream aborts (since it represents the client's only persistent connection), or
  2. A new callback like onsessiondisconnected that fires specifically for SSE stream drops, keeping onclose reserved for explicit termination.

Option 1 seems simplest and matches the semantic intent of onclose — the client is gone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions