Skip to content

bug(testing): SDK Streamable HTTP client leaves async allocations the leak lane cannot distinguish from framework leaks #335

Description

@cyanheads

mcp-ts-core version

0.11.1

Runtime

Node

Runtime version

Node 24

Transport

HTTP (Streamable HTTP)

OS

macOS (Darwin 25.1.0)

Description

The test:leaks lane (vitest --detect-async-leaks) reports outstanding promise and SSE allocations attributable to the MCP TypeScript SDK's Streamable HTTP client, not to framework code. The allocations persist in isolated tests that do nothing but construct the client and close it.

The framework's own bounded shutdown passes: closePerRequestInstances closes transport and server under a timeout with a failure metric, and the per-request instances are released. What the detector still sees is internal to the SDK client's own reconnect/stream bookkeeping, which the public close() does not appear to settle.

Consequence: the lane cannot be run as a hard gate on suites that exercise the SDK client, because a clean run and a leaking run are indistinguishable. Framework-origin leaks would be masked by the constant background.

Steps to reproduce

  1. Write a test that constructs the SDK's Streamable HTTP client against a running server, then calls close() and nothing else.
  2. Run it under bun run test:leaks.
  3. The detector reports outstanding allocations despite the close resolving.

Expected behavior

A close-only test leaves no outstanding async resources, so the leak lane can gate framework regressions.

Actual behavior

Outstanding promise/SSE allocations remain after close() resolves, originating in SDK client internals.

Additional context

Needs upstream resolution in either the SDK or the detector before the lane can gate. Until then test:leaks runs in CI (.github/workflows/ci.yml) as a signal to read, not a gate — the framework-side shutdown path it was added to protect is covered by explicit close assertions instead.

Track alongside #305 (SDK v2 adoption audit) — an SDK-side fix may land there.

Metadata

Metadata

Assignees

Labels

blocked-by-sdkFix requires changes in @modelcontextprotocol/sdkbugSomething isn't workingsdk-v2TypeScript SDK v2 / protocol 2026-07-28 adoption campaign

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions