AI Development

What Did A2A Extensions Ship on September 9? AI Agent Extension Mechanism and JSON Protocol (2026)

About 15 min read

On September 9, 2025, Google published A2A Extensions on the Developers Blog: a pluggable way to add domain capabilities to the Agent2Agent protocol. By 2026, this pattern—URI identifiers, Agent Card JSON declarations, and A2A-Extensions header negotiation—has become the third piece of multi-agent interoperability, alongside Function Calling and MCP. This article reconstructs what shipped that day, then unpacks how to write, negotiate, and ship the JSON under the current spec.

Quick overview

Dimension Details
Official release 2025-09-09 Google Developers Blog A2A Extensions: Empowering Custom Agent Functionality
Core deliverable Optional protocol extensions identified by URI: new data, new constraints, new RPCs, new state machines
JSON carrier capabilities.extensions[] on the Agent Card
Negotiation HTTP header A2A-Extensions; off by default
2026 role A2A handles agent interoperability; Extensions handle domain customization; they do not replace MCP or Function Calling

What shipped on September 9?

A2A (Agent2Agent) already specifies how agents discover each other, send tasks, and stream results back. The core protocol must stay generic—it cannot bake in vertical features such as voice latency broadcasts, end-to-end tracing, or zero-trust handshakes. On September 9, 2025, Google engineers answered that gap in an official post: Extensions.

What landed that day was not a single new RPC, but a full open extension mechanism:

  • Anyone can define, publish, and implement an extension, identified by a unique URI (versioned URIs are recommended, such as https://example.com/ext/my-extension/v1).
  • Agents declare the extensions they support in the Agent Card (a JSON document that describes capabilities).
  • Clients activate per request with an HTTP header; clients that never declare an extension still follow the core protocol and are not broken.
  • The official Hello World stamps timestamps onto the metadata of Message / Artifact.

By 2026, the spec lives in the A2A Extensions topic, and a governance framework has appeared (official extensions use the https://a2a-protocol.org/extensions/ prefix). The rest of this article unpacks the mechanism as a JSON protocol.

A2A protocol and Agent Card JSON

Think of the Agent Card as an agent's machine-readable business card: name, description, entry URL, input/output MIME types, skill list, and capabilities. Extensions hang off capabilities—they are not a separate file.

A Card that advertises extensions looks roughly like this (structure from the official sample; field names follow the current spec):

{
  "name": "Magic 8-ball",
  "description": "An agent that can tell your future... maybe.",
  "version": "0.1.0",
  "url": "https://example.com/agents/eightball",
  "capabilities": {
    "streaming": true,
    "extensions": [
      {
        "uri": "https://example.com/ext/konami-code/v1",
        "description": "Provide cheat codes to unlock new fortunes",
        "required": false,
        "params": {
          "hints": [
            "When your sims need extra cash fast"
          ]
        }
      }
    ]
  },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "skills": [
    {
      "id": "fortune",
      "name": "Fortune teller",
      "description": "Seek advice from the mystical magic 8-ball",
      "tags": ["mystical"]
    }
  ]
}

When debugging this JSON, use JSONSort formatting first to confirm brackets and commas, then check the Schema to see whether extensions[] is missing fields. The Agent Card is published on the network—never put secrets in params.

Extension mechanism: declare, off by default, activate per request

The design goal of Extensions is to extend A2A without tearing the core standard. The spec draws several boundaries:

  1. Off by default. Clients that do not know the extension can still call core methods and get a baseline experience.
  2. Client opt-in. Send A2A-Extensions on the HTTP request, with a comma-separated list of URIs.
  3. The Agent ignores unsupported URIs and echoes the actually activated extensions on the response header.
  4. required: true is a hard dependency. If the client does not activate or comply, the Agent should reject the request. Do not mark data-display extensions as required.

Extensions can depend on other extensions (required or optional). The spec requires those dependencies to be documented in the extension write-up; the Client must include dependency URIs when activating. Version numbers belong in the URI: a breaking change must get a new URI, and the Agent must not silently fall back to another version.

AgentExtension JSON fields

Field Type Meaning
uri string Unique identifier for the extension. Implementers use it to decide whether to activate; Clients use it to judge compatibility.
description string Explains how this Agent uses the extension. Full semantics belong in the extension specification.
required boolean When true, the Client must understand and comply, or the request should be rejected.
params object The extension's own configuration. Field meanings are defined by the extension spec; they can hold defaults or Agent-side declarations.

The spec also draws a hard line so extensions do not break core type validation: do not add or remove required fields on protocol-defined data structures—put custom attributes in the existing metadata map; do not add new values to enums—put extra semantics in metadata as well. Those two rules directly determine what your JSON should look like.

Request negotiation: HTTP header + JSON-RPC message

Activation happens on every HTTP request, not as a permanent “once connected, always on” switch. A typical request (official Hello World style):

POST /agents/eightball HTTP/1.1
Host: example.com
Content-Type: application/json
A2A-Extensions: https://example.com/ext/konami-code/v1

{
  "jsonrpc": "2.0",
  "method": "SendMessage",
  "id": "1",
  "params": {
    "message": {
      "messageId": "1",
      "role": "ROLE_USER",
      "parts": [{"text": "Oh magic 8-ball, will it rain today?"}]
    },
    "metadata": {
      "https://example.com/ext/konami-code/v1/code": "motherlode"
    }
  }
}

The matching response should echo the extensions that were successfully activated:

HTTP/1.1 200 OK
Content-Type: application/json
A2A-Extensions: https://example.com/ext/konami-code/v1

{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "message": {
      "messageId": "2",
      "role": "ROLE_AGENT",
      "parts": [{"text": "That's a bingo!"}]
    }
  }
}

Note that keys in params.metadata are the extension URI plus a path suffix, not arbitrary short field names. That way multiple extensions can stuff data into the same JSON-RPC payload without colliding. When an extension “does nothing,” first check whether the request header carries the URI, then diff the request/response JSON—JSON Diff is a good fit for comparing metadata before and after activation.

Four extension types: data, Profile, method, state machine

The spec deliberately keeps “what an extension can do” broad, but the uses you can foresee in 2026 fold into four types:

  • Data-only: Expose extra structured information on the Agent Card without changing the request-response flow. Example: GDPR compliance fields. These should not be marked required: true.
  • Profile: Layer stricter structure or state constraints on core messages—a profile over A2A. Example: require every parts entry to be a DataPart that matches a Schema; or, when TaskStatus.state === "working", use metadata["generating-image"] as a sub-state.
  • Extended Skills (method type): Add RPCs outside the core set. Example: a task-history extension adds tasks/search, giving the Agent a “searchable historical tasks” skill.
  • State-machine: Add states or transitions to the task state machine. This is the easiest type to cross the red line—new semantics must go in metadata, not by changing the core enum.

Case studies named on launch day

Google's post did not stop at the abstract mechanism. It listed extensions already in use, so you can see what the JSON should carry.

Traceability: the core message is ResponseTrace—a structured log independent of the main protocol that records the steps an Agent took. Each Step is either a ToolInvocation (calling a tool/API) or an AgentInvocation (calling another Agent). Steps can nest: if a downstream Agent also supports the extension, its trace hangs under the upstream step, forming an end-to-end call tree. That is essential for evaluating multi-agent collaboration and locating errors, yet it does not need to live in A2A core.

Twilio Latency Extension: voice Agents (ConversationRelay) need to broadcast latency so they can pick the best downstream model or degrade gracefully. Latency is not a core Agent Card field; Twilio fills the gap with an extension—a textbook case of “domain data should not pollute the core protocol.”

Identity Machines: use an extension for zero-trust handshakes between Agents. Before a task is delegated, a policy gate checks custom conditions such as purpose, budget, capabilities, model, and PII status. The JSON here carries policy context, not chat text.

The post also mentioned Ethereum's ERC-8004 direction: on-chain identity, reputation, and verification registries as a trust layer for cross-organization Agents. It may not ship as an A2A Extension, but it illustrates the same split—the core protocol solves “how we talk”; extensions and external standards solve “why we trust.”

How does this relate to MCP and Function Calling?

All three emit JSON, but they sit at different layers and should not replace each other in 2026:

Layer What the JSON does Typical fields
Function Calling Inside the model API: describes a single callable function tools[] / tool_calls
MCP Tool Schema Tool supply: an external Server exposes capabilities inputSchema
A2A Extensions Agent interoperability: overlay domain capabilities on the peer protocol capabilities.extensions[]

A common architecture is layered: MCP Server provides tools → the host maps those tools to the model's Function Calling → Agents dispatch tasks over A2A and use Extensions to carry cross-agent data such as traces, latency, and identity. For a JSON comparison of the first two layers, see the previous article MCP Tool Schema vs Function Calling.

An extension spec should at least document: the URI list, the schema for params, extra data structures between Client and Agent, and any new request-response flows. In practice:

  • Keep a JSON Schema for AgentExtension.params and another for metadata keys.
  • Validate sample payloads in CI; treat the Agent Card as a public API contract.
  • Treat all extension-related input as untrusted data: parse first, then validate.

For JSON Schema writing, see this site's JSON Schema complete tutorial. Local formatting, syntax checks, and multi-version Diff can be done with JSONSort—no need to upload Cards that contain policy or identity information to a third-party site.

Common pitfalls

  • Treating an Extension as “just add fields.” Core structures cannot change; new data goes in metadata.
  • Marking a data-only extension as required. That needlessly rejects a large number of clients.
  • URIs without a version. Breaking changes have nowhere to go, and negotiation gets messy.
  • Falling back to an old implementation when versions do not match. The spec says ignore that activation request, not silently compat.
  • New RPCs bypassing existing auth. Extension methods must use the same authentication and authorization as core methods.
  • Conflating this with the MCP tool list. MCP answers “which tools exist”; an A2A Extension answers “how two Agents talk under domain rules.”

FAQ

Were A2A Extensions released on September 9, 2026?

The official blog date is September 9, 2025. People still search “what shipped” by that date in 2026; the mechanism is already in the current A2A spec, with ongoing governance and sample extensions (Traceability, Timestamp, Secure Passport, and others).

Must I implement extensions to use A2A?

No. Extensions are off by default. You only need to activate and comply when the other Agent Card marks an extension as required.

Should extension JSON go in the message body or the HTTP header?

The activation list goes in the A2A-Extensions header; business data carried by the extension goes in JSON-RPC params.metadata (or another location specified by the spec). The header negotiates; the JSON carries the payload.

How do I debug an Agent Card and extension metadata?

Format the Card locally with JSONSort, validate the Schema, and diff the extensions arrays of two versions. Do not paste JSON that contains identity or policy into online tools.

Conclusion

What shipped on September 9 was not another vendor-private API, but A2A's open extension layer: name capabilities with URIs, declare them in Agent Card JSON, activate them per request with A2A-Extensions, and carry domain data in metadata. When you build multi-agent systems in 2026: core conversation on A2A, tool supply on MCP, model intent on Function Calling, vertical needs on Extensions—each layer owns one job, with JSON Schema as the single source of truth for parameters and extension data.

Further reading

Changelog: initial release