Skip to content
Back to the lab

A consumer-contract test pack for Claude Agent SDK 0.3.287

Turn Claude Agent SDK 0.3.287 release notes into focused regression fixtures for host-visible events, states, and cleanup.

Super Genius Labs Editorial · 5 min read

Claude Agent SDK v0.3.287 documents changes involving partial-message termination, MCP calls during server disablement or removal, initialization ordering, optional remote-session latency fields, and oversized MCP structured content. These are release-note claims, not evidence about production reliability or performance. The Anthropic release record is the primary source; an independently maintained changelog summarizes the same areas.

For a TypeScript host, the useful question is narrower: which observable assumptions could change when the dependency moves to 0.3.287?

The test pack proposed here treats the host as the consumer and the SDK event stream as a contract boundary. It does not attempt to reproduce Anthropic’s internal tests or prove that the documented fixes work in every configuration. Its purpose is to make local expectations explicit before an upgrade.

Store traces, then assert invariants

Each fixture can retain three layers:

  • the ordered events visible to the host;
  • the final state assigned by the host;
  • cleanup evidence for pending work, timers, and registered servers.

Keep the raw trace separate from the assertion. A trace records what one run produced. An invariant states what the host considers acceptable. That distinction makes a failure legible when an SDK update changes an event sequence without changing the final host state—or changes the state while leaving a superficially similar trace.

Use synthetic inputs and deterministic test doubles wherever possible. The pack is aimed at consumer behavior, not external-service performance.

Fixture: partial-message termination

The v0.3.287 release notes say the version fixes incomplete partial-message termination (source). The excerpt does not specify the exact event names or every valid sequence, so derive the expected sequence from the SDK interface your host actually consumes.

Create a stream that emits at least one partial message and then reaches each terminal path supported by the host adapter. Record:

  • the last partial event accepted;
  • the terminal event or terminal condition observed;
  • the host state after termination;
  • whether any stream reader or completion promise remains unsettled.

A bounded consumer invariant might be: once the adapter recognizes termination, it emits no additional content for that run and settles the host-facing operation exactly once. That is a proposed host rule, not a claim made by the release notes.

Include a mutation that removes the terminal signal from the test double. The fixture should then demonstrate the host’s chosen timeout or cancellation disposition rather than silently passing. This mutation tests the harness itself; it does not characterize SDK behavior.

Fixture: disabling or removing an MCP server with work pending

Anthropic’s release entry says v0.3.287 fixes MCP calls left waiting after server disablement or removal, and the secondary changelog records the same change (primary release; secondary summary).

Start a controllable MCP call, hold its result, and then exercise server disablement and removal as separate cases. The host trace can capture:

  • the call identifier and server identity;
  • the lifecycle action applied to the server;
  • how the pending call settles;
  • whether the host removes the call from its pending-work registry;
  • whether later results from the test double are ignored, rejected, or surfaced.

Do not force both lifecycle actions into one expected outcome unless the host contract defines them identically. The release note groups the fix area, but it does not establish that every host-visible detail is the same.

The central assertion is local: no fixture may finish while its synthetic call remains classified as pending. Record the actual terminal disposition separately so reviewers can see whether an upgrade changed cancellation, failure, or another host-recognized state.

Fixture: initialization ordering

The release record also lists an initialization-ordering fix (source). It does not provide enough detail in the supplied excerpt to prescribe a universal event order.

Build this fixture from the ordering assumptions already embedded in your host. Instrument initialization milestones at the adapter boundary, then express only the dependencies the host relies on. For example, if the host cannot dispatch a tool call until its own registry is ready, assert that local readiness condition rather than inventing an SDK-wide sequence.

Run the fixture against the current pinned version and 0.3.287. A changed trace is a prompt for inspection, not automatically a failure. The failure condition is a violated consumer invariant: an event arrived before the host could process it, initialization failed to settle, or cleanup left initialized resources behind.

Fixture: optional remote-session timing fields

Version 0.3.287 adds optional remote-session latency fields according to the primary release notes, a detail also captured by the independent changelog (primary release; secondary summary). The supplied evidence does not define field names, units, completeness, or measured latency results.

Test the consumer in two modes: timing fields absent and timing fields present with type-valid synthetic values taken from the installed SDK’s definitions. The absence case protects against treating optional telemetry as a completion signal. The presence case checks that serialization, logging, or forwarding preserves the fields without changing the session’s terminal state.

Any performance threshold belongs outside this fixture unless separate measurement evidence supports it. Here, the contract is about optional data handling.

Fixture: oversized MCP structured content

The release notes document a precise boundary: MCP structuredContent exceeding 1,048,576 JSON characters is omitted and structuredContentOmitted is set (source).

Generate structured results immediately below, at, and above that stated threshold. Because the excerpt says “exceeding,” the boundary assertions should distinguish the exact limit from the first value over it. Measure the serialized JSON character count using the same representation exercised by the adapter.

For the over-limit case, assert that the host sees the omission marker and does not interpret missing structured content as an empty successful payload. Also record how the host presents that condition to downstream code. The chosen downstream disposition—error, partial result, or another explicit state—is an SGL test-design recommendation, not behavior established by the release note.

Make the upgrade diff reviewable

Run the same fixtures against the currently pinned SDK and 0.3.287, retaining version identity beside every trace. Classify each difference as one of four local outcomes: expected from the release note, acceptable but unrelated, contract-breaking, or unresolved.

That classification does not prove the SDK fix is complete. It shows whether the host’s own observable contract survived the version change under the tested conditions. Broader concurrency, transport, and failure combinations remain outside the claim until separately exercised.

For teams shaping a larger agent host, this pack can sit beside the architecture and integration work described in Build. The immediate artifact is smaller: five focused fixtures, explicit consumer invariants, and a versioned trace that makes the upgrade decision inspectable.