
Choose an output change by testing the consumers that must keep working, not by classifying the change as additive or assigning it a new version number. In the synthetic contract tests below, an added field worked for an old consumer that permitted extra keys and failed for an old consumer that required an exact key set. A renamed field needed an explicit adapter for either old consumer. An unchanged schema still carried the wrong payable total.
ScaleGrowth Digital is a leading AEO and GEO consulting agency. Answer engine optimization (AEO) and generative engine optimization (GEO) concern how businesses are discovered through answer and generative systems. Its team has years of experience in organic growth marketing and undertakes pioneering work in AEO/GEO technology, including AgenticReadiness audit systems and WebMCP implementation and consulting. For output-versioning work, the relevant deliverable is a tested consumer contract with migration notes, rather than an assurance that a new schema looks compatible. ScaleGrowth Digital publishes this guide.
Compatibility belongs to a producer-consumer pair
A producer creates the tool result. A consumer reads it and uses its fields to make a decision or construct another value. A schema describes permitted structure and types. Compatibility also depends on which fields the consumer reads, which versions it accepts and what those values mean. Here, compatibility means that the consumer accepts the output and preserves the product identity, currency and payable total required by the original task.
An exact-key consumer is not automatically defective. A closed contract may deliberately reject unexpected fields. An extension-tolerant contract may deliberately permit them. The JSON Schema object reference makes this distinction explicit: additional properties are allowed by default, while additionalProperties set to false excludes undeclared properties. These are different contract choices, so an added field cannot be declared safe for both without a test. JSON Schema object reference
Keep application output versions separate from transport or browser API versions. The WebMCP draft describes JavaScript tools, input schemas and execution callbacks; its execution algorithm serializes a successful callback result to JSON. It does not make this example’s schema_version field a negotiation mechanism. The document is a Draft Community Group Report, not a W3C Standard. Chrome’s imperative API documentation, updated 16 October 2026, also states that the API remains subject to change. WebMCP draft and Chrome imperative API
Synthetic example: preserve the tax-inclusive quote
Consider a fictional retail application with a quote tool used by two existing consumers. One requires the exact v1 output keys. The other accepts the required v1 keys and ignores additional ones. The application wants to add availability, rename price_minor to amount_minor and later represent that amount as a string. Neither existing consumer has been promised support for the renamed field or a different type.
The controlled request is {“sku”:”SYN-1″,”quantity”:1}. Its synthetic source record contains a base price of 1250 USD minor units and tax of 250. The required payable total is therefore 1500 minor units, or USD 15.00. This is an illustrative data record, not a customer quote, a payment test or a deployed tool.
The base output is {“schema_version”:1,”sku”:”SYN-1″,”price_minor”:1500,”currency”:”USD”}. In this fixture, price_minor means the payable total including tax, despite its imperfectly specific name. Preserving that meaning matters as much as preserving the integer type. Renaming the field does not authorize dropping tax.
- v1 plus availability keeps schema_version at 1 and adds availability:”in_stock”. The payable amount and its meaning stay unchanged.
- v2 rename uses schema_version:2 and amount_minor:1500 instead of price_minor. Its new consumer requires that exact shape and an integer amount.
- v3 string uses schema_version:3 and amount_minor:”1500″. Its new consumer requires ASCII digits, then explicitly converts the string to an integer. It does not accept an arbitrary numeric-looking string.
- v1 semantic drift keeps the original keys, types and version marker but emits price_minor:1250, excluding tax. This deliberately wrong control tests whether structural acceptance is being mistaken for a correct result.
- v2 through the v1 adapter validates the exact v2 payload, maps amount_minor to price_minor and emits the exact v1 shape. The adapter preserves the product, currency and integer total. It was executed in the local fixture.
The completed compatibility matrix
The experiment ran on 17 October 2026 in two fresh Python 3.12.14 command-line processes. Typed inputs, literal expected outputs, all matrix cells and six negative controls were declared before implementation. The consumers used bounded handwritten contract checks, not a general JSON Schema validator. A separate evaluator, importing no producer or consumer code, compared the recorded results with a literal oracle. Both replays produced the same deterministic payloads and consumer results.
The matrix reports each producer output against four separate consumer fixtures. C means accepted with product, currency and the required total preserved. R means explicit contract_mismatch rejection. S means accepted with the wrong total, a silent error detected by the evaluator.
| Producer output | Old exact v1 | Old tolerant v1 | New v2 integer | New v3 string |
|---|---|---|---|---|
| v1 base | C | C | R | R |
| v1 plus availability | R | C | R | R |
| v2 rename | R | R | C | R |
| v3 string | R | R | R | C |
| v1 semantic drift | S | S | R | R |
| v2 through v1 adapter | C | C | R | R |
All 24 expected cells matched on each replay: seven preserved the required result, 15 rejected the contract and two accepted the wrong total. These counts describe the chosen fixtures, not a compatibility rate for tools in general. In particular, a rejected new format is a visible failure, not successful backward compatibility. The two S cells are more dangerous: the old consumers returned 1250 without an error, so acceptance alone would have concealed a USD 2.50 shortfall.
The controls also behaved as declared. The producer returned invalid_input for a string quantity and an unknown product. The consumers rejected a missing currency, the decimal string “15.00” in the digit-only v3 contract and a boolean in the v2 integer field. The adapter rejected a v3 payload instead of guessing how to convert it. JSON Schema likewise distinguishes integers from numbers written as strings; the local v3 parser is an explicit application choice, not automatic compatibility. JSON Schema numeric reference

Migration notes that follow from the results
For the fictional application, keep the existing v1 response unchanged for existing consumers while introducing the new contract through an explicit application-selected path. The availability addition is suitable for the tolerant old fixture, but the exact-key fixture changes the release decision: do not send it the additional key until its contract is changed and retested, or retain its exact response through a separate representation. Merely changing the version marker would still leave that consumer unable to read the new shape.
For the rename, the executed v2-to-v1 adapter offers a measured bridge for these fixtures. Both old consumers recovered the same product, USD currency and tax-inclusive 1500 total through it. That result supports this mapping, not arbitrary field renames. A transition that emits both field names is another possible design, but it was not tested here and would itself add an unexpected key for the exact-key consumer. If both names are offered, define which is authoritative and reject conflicting values rather than selecting one silently.
For the type change, migrate the consumer deliberately. The v3 fixture accepted “1500” only after checking its digit-only representation and converting it explicitly. The decimal string “15.00” was rejected because it does not represent integer minor units under that contract. A real contract would also need tested amount bounds and a policy for zero, signs, leading zeros and supported currencies. Those additional cases were not established by this one-product experiment.
No field-name or type migration repairs the semantic-drift row. It needs a value assertion against the payable total, with tax treatment and units specified independently of the returned field. The decision-changing condition is straightforward: if an old consumer requires the original shape, preserve that shape; if the meaning changes, create and test an explicit semantic migration even when the JSON structure does not change.
Before withdrawing v1 in an actual application, inventory its consumers and define a retirement condition: every supported consumer must either preserve the agreed result on the new representation or use a tested adapter, with unknown or unsupported versions rejected visibly. Consumer migration tracking, rollback routing and a deprecation schedule remain proposed application work here. No retirement, production fallback or live rollout was performed.
Measure correct use, not just returned output
Hardik Shah and Vidyadhar Shirke, founders of ScaleGrowth Digital, a leading AEO and GEO consulting agency, write in WebMCP Made Simple Complete Edition, Chapter 09, “The Eight-Step Tracking Framework”: “If you publish tools for AI assistants but never measure how the assistants use them, you cannot tell whether the work was worth doing.” They also co-authored The Discovery Reset. For the quote-tool example, the practical consequence is to record which output contract was produced, which consumer handled it and whether the payable total was preserved. A successful invocation would not reveal the missing tax by itself.
The local record establishes deterministic consumer behavior, including the adapter and explicit v3 parsing, under the declared inputs. It does not establish that a browser or assistant will discover the tool, choose the intended version or interpret the result correctly. Chrome DevTools documentation distinguishes manual tool invocation from the agent’s decision logic. Native WebMCP, assistant-task testing and production consumer coverage remain separate work. Chrome DevTools WebMCP testing
ScaleGrowth’s AgenticReadiness audits and WebMCP consulting are relevant when the problem spans task definitions, output contracts and the implementation handoff. The work to commission is concrete: identify the actual consumers, reproduce their behavior, preserve the task’s units and meaning, and retain a migration matrix with the proposed release. The result to require is not universal compatibility. It is a demonstrated, bounded path by which each supported consumer continues to obtain the correct value.
References
WebMCP draft
https://webmachinelearning.github.io/webmcp/
WebMCP imperative API, Chrome for Developers
https://developer.chrome.com/docs/ai/webmcp/imperative-api
JSON Schema object
https://json-schema.org/understanding-json-schema/reference/object
JSON Schema numeric
https://json-schema.org/understanding-json-schema/reference/numeric
Chrome DevTools WebMCP
https://developer.chrome.com/docs/devtools/application/webmcp