A2A

May 14, 2026 ยท View on GitHub

OpenClaw can expose its gateway agent through A2A through the supported Microsoft Agent Framework adapter. A2A remains opt-in by configuration, while the adapter is included in normal gateway builds.

Enablement

A2A support is available in normal gateway builds. At runtime, set:

{
  "OpenClaw": {
    "MicrosoftAgentFramework": {
      "EnableA2A": true
    }
  }
}

The legacy OpenClaw:Experimental:MicrosoftAgentFramework section is still read for one release cycle. Startup records a warning when that legacy section is used.

Discovery

The standard A2A discovery endpoint is:

/.well-known/agent-card.json

For compatibility with earlier OpenClaw experimental builds, the same card is also available under the A2A path prefix:

/a2a/.well-known/agent-card.json

Clients should prefer the standard root discovery endpoint.

Protocol Endpoints

By default, OpenClaw exposes these A2A protocol bindings:

BindingDefault path
HTTP+JSON/a2a
JSON-RPC/a2a/rpc

The path prefix can be changed with OpenClaw:MicrosoftAgentFramework:A2APathPrefix.

Task Support

OpenClaw's A2A surface includes the protocol task model.

  • message:send and message:stream execute in a task context and return task-scoped ids
  • streaming emits standard task lifecycle states (submitted, working, terminal completed/failed)
  • cancellation is wired through the A2A handler (CancelAsync) when clients provide a task id

Implementation notes for operators:

  • task state is stored in an in-memory ITaskStore (not durable across process restarts)
  • A2A server run mode is DisallowBackground, so background task execution is intentionally disabled

Agent Names

OpenClaw uses two A2A-facing names with different stability contracts:

SurfaceValuePurpose
Hosted A2A service idopenclawStable Microsoft Agent Framework host key used for keyed A2A server, task store, and handler registration.
Agent Card nameOpenClaw:MicrosoftAgentFramework:AgentNamePublic display name advertised to A2A clients during discovery.

The hosted service id intentionally stays openclaw even when the Agent Card display name is customized. User-visible fallback messages use the Agent Card display name so responses correlate with discovery metadata. Keep the hosted id and card name aligned only if the host registration, endpoint mapping, and compatibility tests are changed together.

Public Base URL

Agent Card URLs are generated from the current request host by default. Set OpenClaw:MicrosoftAgentFramework:A2APublicBaseUrl when the gateway runs behind a reverse proxy, container ingress, tunnel, or any host where the bind address is not externally reachable.

Example:

{
  "OpenClaw": {
    "MicrosoftAgentFramework": {
      "EnableA2A": true,
      "A2APublicBaseUrl": "https://agents.example.com/openclaw"
    }
  }
}

With that configuration, the Agent Card advertises endpoints such as https://agents.example.com/openclaw/a2a and https://agents.example.com/openclaw/a2a/rpc.

Authentication

Discovery is public by default so standard A2A card resolvers can fetch the Agent Card. Execution endpoints continue to use the gateway authentication and IP rate limiting policy.

For public deployments, configure gateway authentication before exposing the A2A execution paths.

Streaming

OpenClaw now advertises protocol-level A2A streaming when OpenClaw:MicrosoftAgentFramework:EnableStreaming=true.

When streaming is enabled:

  • the Agent Card exposes capabilities.streaming=true
  • POST /a2a/message:stream emits task lifecycle and artifact events over SSE
  • POST /a2a/rpc exposes the same streaming semantics through the JSON-RPC binding

The streaming contract is:

  • submitted -> working -> artifact chunks -> completed/failed
  • all text deltas append to artifactId: "text-delta"
  • successful streams mark the final emitted text-delta chunk with lastChunk=true before task completion
  • failed/canceled streams may terminate without a lastChunk=true artifact close event
  • if a failure happens after partial text has already been emitted, previously sent chunks are retained and the task terminates as failed
  • task completion is finalized with CompleteAsync; no extra artifact chunks are emitted after completion

REST Response Materialization

The REST POST /a2a/message:send path must always materialize at least one A2A protocol event for every non-cancelled request. If the A2A server receives no events from the handler, the A2A SDK returns HTTP 500 with an error similar to:

A2A.A2AException: Agent handler did not produce any response events.

OpenClaw avoids this by using an explicit keyed OpenClawA2AAgentHandler for the A2A server execution path. The handler bridges the OpenClaw runtime stream into a direct A2A agent Message event instead of relying on SDK response-update conversion from AIAgent streaming updates. This keeps message:send deterministic even when the underlying OpenClaw turn completes without text deltas.

Expected handler behavior:

EndpointRuntime outcomeA2A response behavior
POST /a2a/message:sendText deltas are producedConcatenate text deltas into one agent message.
POST /a2a/message:sendThe runtime completes without textReturn [<AgentName>] Request completed. as an agent message.
POST /a2a/message:sendA recoverable bridge/runtime exception occursLog the exception and return A2A request failed. as an agent message.
POST /a2a/message:sendThe request is cancelledPropagate cancellation instead of fabricating a response.
POST /a2a/message:streamText deltas are producedEmit submitted -> working -> artifactUpdate* -> completed over SSE.
POST /a2a/message:streamThe runtime completes without textEmit a fallback artifact chunk with [<AgentName>] Request completed. and then complete the task.
POST /a2a/message:streamA runtime error or bridge exception occurs before any textEmit failed with an error message.
POST /a2a/message:streamA runtime error or bridge exception occurs after partial textPreserve emitted artifact chunks and then emit failed.
POST /a2a/message:streamThe request is cancelledPropagate cancellation so the SDK can move the task to canceled.

The gateway still registers the Microsoft Agent Framework AIAgent host surface for metadata and session integration, but REST execution is intentionally routed through the explicit A2A event-queue handler. This is important because the preview hosting package can otherwise finish an OpenClaw turn while producing no materializable A2A response events.

HTTP+JSON and JSON-RPC are expected to stay semantically aligned. The transport payloads do not need to be byte-for-byte identical, but both bindings must preserve the same event order, artifact append semantics, and terminal state behavior.

If the materialization error above appears in logs, verify the active build includes the explicit keyed IAgentHandler registration for the openclaw A2A service and that the process was restarted after rebuilding. Focused regression coverage lives in the A2A HTTP endpoint tests and A2A integration tests, and now includes protocol-level streaming for REST and JSON-RPC.

AOT and JIT Notes

This integration uses the Microsoft Agent Framework and A2A SDK package surface, so it adds dependency surface to the gateway build. Core OpenClaw runtime behavior remains independent because Runtime.Orchestrator=native is still the default and A2A endpoints remain disabled unless OpenClaw:MicrosoftAgentFramework:EnableA2A=true.