modelcontextprotocol / modelcontextprotocol/typescript-sdk

Undici instrumentation marks successful MCP requests as aborted due to premature AbortController.abort() in SSE / StreamableHTTP transports

Open
#1,231 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement help wanted P2
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

When using the MCP TypeScript SDK (SSEClientTransport / StreamableHTTPClientTransport) with Undici instrumentation (e.g., OpenTelemetry), successful MCP POST requests are being reported as aborted.

This happens because close() immediately calls:

this._abortController?.abort()

If a POST response is still being processed, Undici receives the abort signal and marks the span as an error, even though the server returned 200 OK. This results in spans like:

UND_ERR_ABORTED: The operation was aborted

for successful requests.


Impact
  • Successful MCP requests show up as failed in traces
  • Undici logs aborted errors
  • Misleading telemetry in distributed tracing
  • Connections stay open until Undici’s idle timeout (~10–14 seconds)

Reproduction
  1. Enable OTel Undici instrumentation

  2. Use SSEClientTransport or StreamableHTTPClientTransport

  3. Send any POST request (initialize, callTool, etc.)

  4. Immediately call client.close()

  5. Observe:

    • Response is 200 OK
    • Undici reports UND_ERR_ABORTED
    • Span is marked as failed

Request

Could the SDK:

  1. Avoid calling AbortController.abort() while requests are still in-flight
  2. Optionally provide a graceful close mode that waits for active requests to finish

This would prevent Undici from misclassifying successful MCP requests as aborted and keep telemetry accurate.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at close() in SSEClientTransport and StreamableHTTPClientTransport, then reproduce the issue with OTel Undici instrumentation and an immediate client.close() after a POST. Done means successful 200 OK requests are not reported as aborted, with any graceful-close behavior covering in-flight requests.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.