Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

a2a-cpp C++20 Agent2Agent (A2A) SDK Documentation

a2a-cpp is a C++20 SDK for building Agent2Agent (A2A) protocol clients and servers. The current documented release focuses on production-oriented protocol coverage: REST, JSON-RPC, and gRPC transports; Agent Card discovery; task lifecycle APIs; streaming; push notification configuration APIs; authentication metadata propagation; interceptors; CMake package exports; and vcpkg-oriented packaging.

What is included

  • Client API: SendMessage, GetTask, ListTasks, CancelTask, streaming send/subscribe, and task push-notification config lifecycle calls.
  • Server API: executor-driven dispatch for REST, JSON-RPC, and gRPC transports.
  • Discovery: public and extended Agent Card fetch plus preferred-interface resolution.
  • Streaming: client observers, cancellable stream handles, and server stream sessions.
  • Authentication hooks: client credential providers and server request metadata extraction.
  • Operational extensions: client/server interceptors, required-extension validation, task stores, task history ordering, UUIDv7 task IDs, and optional PostgreSQL stores.
  • Build integration: CMake 3.25+, C++20, installable CMake package exports, generated protobuf headers, and vcpkg overlay/public-registry preparation.
  1. Installation and Build for toolchain requirements and CMake options.
  2. Quickstart for a copy/paste example flow.
  3. Client Overview or Server Overview, depending on your integration role.
  4. Transports, Streaming, and Authentication for runtime design decisions.
  5. API Reference when you need generated public-header details.

Version and support notes

  • See Releases and Versions for current release details and versioning guidance.
  • The SDK is C++20-only and exports CMake targets under the a2a:: namespace.
  • Package documentation describes vcpkg workflows only.
  • Examples are deterministic and are intended to run without external services unless the example README says otherwise.

Installation and Build

This page reflects the current build surface for the latest documented release.

Prerequisites

Install these tools before configuring the repository:

  • CMake 3.25 or newer.
  • A C++20 compiler, tested primarily with GCC and Clang.
  • Protobuf with protoc.
  • gRPC C++ with grpc_cpp_plugin.
  • clang-format and clang-tidy for contributor validation.
  • Optional: Doxygen for API reference generation.
  • Optional: libcurl for built-in outbound HTTP support.
  • Optional: PostgreSQL client libraries when building PostgreSQL-backed stores.

Configure from source

cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Useful options:

OptionDefaultPurpose
A2A_ENABLE_TESTINGONBuilds unit and integration tests.
A2A_BUILD_EXAMPLESONKeeps the root project compatible with example-related CI messaging; curated examples are built as standalone consumers.
A2A_BUILD_BENCHMARKSOFFBuilds the optional Google Benchmark suite.
A2A_ENABLE_LIBCURLONEnables default buffered outbound HTTP when CURL::libcurl is found.
A2A_ENABLE_POSTGRES_STOREOFFBuilds PostgreSQL task and push-notification stores.

Build and test

cmake --build build --parallel
ctest --test-dir build --output-on-failure

Generate only protobuf outputs when needed:

cmake --build build --target a2a_proto_codegen

Generated headers are written under build/generated/a2a/v1/ and are installed with the SDK.

Install CMake package artifacts

cmake --install build --prefix /tmp/a2a-cpp-install

The install tree includes public headers, generated protobuf headers, libraries, and CMake package files under lib/cmake/a2a_cpp.

Contributor validation

For code changes, run the canonical validation script before opening or updating a PR:

./scripts/verify_changes.sh

The script runs the same major local gates as CI: clang-format dry run, configure/build, tests, and clang-tidy.

For documentation-only mdBook changes, build the book:

mdbook build book

Quickstart: Build and Run Examples

The fastest way to exercise the SDK is through the curated consumer examples. They build the example app sources the same way downstream applications consume the SDK.

1. Run the smallest end-to-end example

cmake -S examples/fetch_content_consumer -B build-example \
  -DA2A_EXAMPLE_APP=hello_agent
cmake --build build-example --parallel
./build-example/a2a_example

hello_agent creates a minimal in-process client/server flow and exits deterministically.

2. Try transport-specific examples

./scripts/run_examples.sh rest_server json_rpc_server grpc_server

These examples cover server transport setup and deterministic request handling across REST, JSON-RPC, and gRPC.

3. Try streaming, push, and auth examples

./scripts/run_examples.sh streaming_client streaming_server push_notifications auth_policy_server

Use these when validating event streams, webhook configuration flows, or server-side auth metadata policy shapes.

4. Consume an installed SDK package

After installing the SDK into a prefix, build the same app source with find_package(a2a_cpp CONFIG REQUIRED):

cmake -S examples/installed_package_consumer -B build-installed-example \
  -DCMAKE_PREFIX_PATH=/tmp/a2a-cpp-install \
  -DA2A_EXAMPLE_APP=hello_agent
cmake --build build-installed-example --parallel
./build-installed-example/a2a_example

5. Validate your local checkout

./scripts/verify_changes.sh

For documentation-only edits, use mdbook build book instead of the full code validation flow.

Client Overview

Use a2a::client::A2AClient with a concrete ClientTransport to call A2A servers.

Client capabilities

  • SendMessage
  • GetTask
  • ListTasks
  • CancelTask
  • SendStreamingMessage
  • SubscribeTask
  • CreateTaskPushNotificationConfig
  • GetTaskPushNotificationConfig
  • ListTaskPushNotificationConfigs
  • DeleteTaskPushNotificationConfig
  • Client interceptors via ClientInterceptor
  • Per-call settings through CallOptions

Typical flow

  1. Fetch an Agent Card with DiscoveryClient.
  2. Select an endpoint with AgentCardResolver::SelectPreferredInterface.
  3. Construct HttpJsonTransport, JsonRpcTransport, or GrpcTransport.
  4. Create A2AClient with the transport.
  5. Invoke task, streaming, or push-notification APIs.
  6. Call Destroy() during shutdown when you need transport cleanup.

Default outbound HTTP

When libcurl is available and A2A_ENABLE_LIBCURL=ON, default constructors/factories can perform buffered outbound REST, JSON-RPC, and discovery calls. For tests, custom TLS policy, mTLS, retries, or embedded runtimes, inject your own requester/fetcher callbacks.

Runnable examples

  • examples/apps/hello_agent/main.cpp
  • examples/apps/simple_client/main.cpp
  • examples/apps/streaming_client/main.cpp
  • examples/apps/push_notifications/main.cpp

Sending Messages

A2AClient::SendMessage starts or continues a task by sending a protobuf lf::a2a::v1::SendMessageRequest through the configured transport.

Request construction guidance

  • Set a stable message.message_id for idempotency and diagnostics.
  • Let the server generate a task ID for new work unless you are intentionally continuing an existing task.
  • Attach push-notification config only when the target Agent Card advertises support and your server policy allows it.
  • Use CallOptions for per-call deadlines, metadata, or auth settings where supported by the transport.

Response handling

The response can contain immediate task state and output data. Persist task identifiers in logs/telemetry so later GetTask, CancelTask, streaming subscription, or push-notification calls can be correlated.

Failure paths to test

  • Network or HTTP/gRPC transport failure.
  • Serialization or protocol validation failure.
  • Auth policy rejection.
  • Unsupported operation or required extension mismatch.
  • Duplicate/retry behavior for repeated message IDs.

Discovery and Agent Cards

Discovery resolves server capabilities before constructing a client transport.

Public and extended cards

DiscoveryClient supports:

  • Fetch(base_url) for the standard Agent Card.
  • FetchExtendedAgentCard(base_url) for the extended Agent Card endpoint.

Fetched cards are cached for kDefaultDiscoveryCacheTtl (300 seconds) unless a different TTL is supplied.

Interface resolution

AgentCardResolver::SelectPreferredInterface(card, preferred) selects a ResolvedInterface for one of:

  • PreferredTransport::kRest
  • PreferredTransport::kJsonRpc
  • PreferredTransport::kGrpc

The result includes the transport, URL, security requirements, and security schemes needed to configure a client.

Operational guidance

  • Validate and log the selected endpoint during startup.
  • Prefer an explicit fallback order when cards advertise multiple transports.
  • Treat discovery metadata as untrusted input until validated.
  • Refresh cached cards after deployment or capability changes.
  • include/a2a/client/discovery.h
  • include/a2a/core/agent_card/agent_card_provider.h
  • include/a2a/server/agent_card/agent_card_serializer.h

Get Task and List Tasks

GetTask retrieves a single task by ID. ListTasks returns a paginated list of tasks through the client abstraction and supported transports.

GetTask flow

  1. Store the task ID from SendMessage or a stream event.
  2. Build lf::a2a::v1::GetTaskRequest.
  3. Call A2AClient::GetTask.
  4. Interpret task status, artifacts, and history according to your application policy.

ListTasks flow

a2a::client::ListTasksRequest contains:

  • page_size
  • page_token

The response includes task values plus next_page_token.

Operational guidance

  • Use bounded polling with backoff when not using streaming.
  • Enforce authorization checks on server-side task visibility.
  • Avoid exposing full task history to clients that do not need it.

Cancel Task

A2AClient::CancelTask asks the server to cancel in-flight work.

When to use cancellation

  • A user aborts an operation.
  • A deadline expires upstream.
  • Supervising logic needs to reclaim compute or queue capacity.

Semantics

Cancellation is best-effort. A task can complete before the cancellation request is processed, and servers can reject cancellation for completed, unknown, or policy-protected tasks.

  • Make higher-level cancellation idempotent.
  • Return or display the latest task state after cancellation attempts.
  • Preserve enough audit data to explain whether the task was canceled, completed, or rejected.

Server Overview

Server integrations implement a2a::server::AgentExecutor and route protocol requests through Dispatcher plus one or more transports.

Server capabilities

  • REST server transport.
  • JSON-RPC server transport.
  • gRPC service transport.
  • Public and extended Agent Card dispatch when a provider is installed.
  • Required extension validation.
  • Server interceptors.
  • Streaming through ServerStreamSession.
  • Task lifecycle helpers, in-memory task store, and optional PostgreSQL stores.
  • Push-notification config CRUD and delivery service abstractions.

Core flow

  1. Implement an executor for task and message behavior.
  2. Create a Dispatcher with the executor and optional Agent Card provider/interceptors.
  3. Attach REST, JSON-RPC, or gRPC transport adapters.
  4. Convert inbound framework requests into transport calls.
  5. Return structured protocol errors instead of transport-specific ad hoc errors.

Task IDs

When an incoming message does not carry message.task_id, the SDK service layer can generate server-side task IDs using UUIDv7. UUIDv7 is sortable and operationally useful, but it leaks approximate creation time. Inject a custom task ID generator if your deployment needs opaque identifiers.

Custom Executors

Implement a2a::server::AgentExecutor to define application behavior.

Required methods

Executors implement task/message operations including:

  • SendMessage
  • SendStreamingMessage
  • GetTask
  • ListTasks
  • CancelTask

Push-notification config methods have default PushNotificationNotSupported behavior and should be overridden only when the server actually supports them.

Request context

Every executor method receives RequestContext. Use it for auth metadata, transport metadata, and request-scoped policy decisions. Treat metadata as untrusted until validated.

Design guidance

  • Keep executor methods small and deterministic.
  • Validate inputs at the boundary.
  • Return a2a::core::Result<T> with structured errors.
  • Avoid shared mutable state unless synchronized and documented.
  • Unit-test executor behavior separately from transport mapping.

REST Server Transport

RestServerTransport maps HTTP+JSON requests onto dispatcher operations.

Responsibilities

  • Validate HTTP method, path, and content type.
  • Parse JSON request bodies into protobuf messages.
  • Populate RequestContext, including auth metadata.
  • Serialize protocol responses and errors back to HTTP responses.

Supported operation shape

REST transport covers core task lifecycle operations, streaming-compatible endpoints where wired by the hosting environment, Agent Card routes, and push-notification config APIs exposed by the dispatcher/executor.

Hosting guidance

The SDK provides protocol mapping, not a full production web server framework. In production, place it behind an HTTP runtime that owns TLS, connection limits, request-size limits, access logs, and graceful shutdown.

Example

See examples/apps/rest_server/main.cpp.

JSON-RPC Server Transport

JsonRpcServerTransport maps JSON-RPC 2.0 method calls to dispatcher operations.

Responsibilities

  • Validate the jsonrpc, id, method, and params envelope fields.
  • Route supported A2A methods to the dispatcher.
  • Return JSON-RPC error objects for invalid requests, unknown methods, and executor failures.
  • Preserve request metadata for auth and audit policy.

Use cases

Use JSON-RPC when method-based routing is easier to integrate than resource-oriented REST paths or when another system already standardizes on JSON-RPC 2.0.

Example

See examples/apps/json_rpc_server/main.cpp.

Push Notifications

The SDK includes task push-notification configuration APIs and server-side delivery abstractions.

Client API surface

A2AClient exposes:

  • CreateTaskPushNotificationConfig
  • GetTaskPushNotificationConfig
  • ListTaskPushNotificationConfigs
  • DeleteTaskPushNotificationConfig

Use these only when the target Agent Card and server policy indicate push-notification support.

Server components

  • PushNotificationService coordinates stored configs and delivery.
  • PushNotificationStore persists webhook configs.
  • PushNotificationDeliveryClient abstracts outbound delivery.
  • HttpPushNotificationDeliveryClient provides a simple libcurl-backed synchronous delivery path when libcurl support is enabled.
  1. Persist task state in your TaskStore or TaskLifecycleService.
  2. Register inline configs from SendMessageRequest when present.
  3. Call NotifyTaskUpdated(task) after status changes.
  4. Propagate delivery failures instead of silently dropping them.
  5. Override push-config CRUD executor methods only when push support is fully configured.

Production guidance

For production, prefer a durable queued delivery client with retries, backoff, webhook URL validation, SSRF controls, credential protection, and delivery telemetry. Keep TLS policy at least as strong as the built-in delivery client, which requires TLS 1.2 or newer for HTTPS URLs.

Example

See examples/apps/push_notifications/main.cpp.

Server Interceptors

Server interceptors let deployments attach cross-cutting behavior around dispatcher operations.

Common uses

  • Authorization and policy checks.
  • Request/response telemetry.
  • Audit logging.
  • Metrics and latency measurement.
  • Required extension enforcement in combination with transport validators.

Design guidance

  • Keep interceptors deterministic and low-latency.
  • Avoid logging secrets or raw credential values.
  • Use structured errors so transports can map failures consistently.
  • Prefer composition: keep business behavior in AgentExecutor and cross-cutting behavior in interceptors.
  • a2a::server::ServerInterceptor
  • a2a::server::Dispatcher::AddInterceptor
  • a2a::client::ClientInterceptor for client-side call hooks

Transports Overview

The SDK separates protocol operations from transport adapters. Applications choose the transport that best matches their deployment boundary and interoperability needs.

Available transports

  • REST: HTTP+JSON resource-oriented integration for clients and servers.
  • JSON-RPC: JSON-RPC 2.0 method dispatch over HTTP-style request handling.
  • gRPC: protobuf/gRPC service integration with unary and streaming RPCs.

Choosing a transport

  • Choose REST when your platform already standardizes on HTTP routing, gateways, or resource-style APIs.
  • Choose JSON-RPC when method-style dispatch is easier to interoperate with or proxy.
  • Choose gRPC when you want protobuf-native contracts, gRPC streaming, or a service mesh that already supports gRPC well.

Shared operational concerns

Regardless of transport, define these policies explicitly:

  • Authentication and authorization boundaries.
  • Protocol version and required-extension handling.
  • Request deadlines and payload limits.
  • Retry and idempotency behavior.
  • Telemetry, audit logs, and stable task/request identifiers.

REST Transport

REST is the HTTP+JSON transport path for clients and servers.

Client side

Use HttpJsonTransport with A2AClient. When libcurl is enabled and found, default outbound buffered HTTP can be used. Otherwise inject an HttpRequester implementation.

Server side

Use RestServerTransport to translate inbound framework requests into dispatcher calls.

Operational considerations

  • Enforce TLS and auth policy at your edge or hosting layer.
  • Set explicit request deadlines and payload limits.
  • Log stable task IDs and request IDs.
  • Validate protocol version headers where required.
  • Prefer injected requesters for custom retry, proxy, mTLS, or observability policy.

JSON-RPC Transport

JSON-RPC transport supports A2A method dispatch over JSON-RPC 2.0 envelopes.

Client side

Use JsonRpcTransport with A2AClient. Default buffered outbound HTTP is available when libcurl is enabled and found; otherwise inject a requester.

Server side

Use JsonRpcServerTransport to decode envelopes, dispatch operations, and encode JSON-RPC responses.

Operational considerations

  • Validate envelope fields strictly.
  • Preserve client-provided request IDs in responses.
  • Map structured SDK errors to consistent JSON-RPC error responses.
  • Include auth metadata in RequestContext only after policy validation.

gRPC Transport

gRPC support is first-class for client and server integrations.

Client side

Use a2a::client::GrpcTransport with a resolved interface and either:

  • a std::shared_ptr<grpc::Channel> for real gRPC calls, or
  • a custom GrpcTransport::RpcClient for tests and embedded adapters.

The transport supports unary task operations, streaming send, task subscription, and push-notification config lifecycle calls.

Server side

a2a::server::GrpcServerTransport implements lf::a2a::v1::A2AService::Service and routes RPCs to the dispatcher.

It supports:

  • SendMessage
  • SendStreamingMessage
  • GetTask
  • ListTasks
  • CancelTask
  • SubscribeToTask
  • Push-notification config RPCs
  • GetExtendedAgentCard

Metadata and extensions

The server transport recognizes A2A metadata such as a2a-version and can validate required extensions through GrpcServerTransportOptions::required_extensions.

Example

See examples/apps/grpc_server/main.cpp.

Streaming

Streaming is available through client APIs and server stream sessions.

Client APIs

  • A2AClient::SendStreamingMessage(request, observer, options)
  • A2AClient::SubscribeTask(request, observer, options)

Implement a2a::client::StreamObserver:

  • OnEvent(const StreamResponse&) for each event.
  • OnError(const core::Error&) for transport or protocol failures.
  • OnCompleted() when the stream finishes normally.

Both calls return a StreamHandle. Call Cancel() to request cancellation and IsActive() to check handle state.

Threading contract

Observer callbacks run on transport-managed background threads. Keep observers alive until stream completion, cancellation, or handle destruction. Callback code should be thread-safe, fast, and non-blocking.

Server side

Executors return std::unique_ptr<ServerStreamSession> from SendStreamingMessage and, optionally, SubscribeTask. A stream session publishes StreamResponse values until it returns an empty optional or an error.

Examples

  • examples/apps/streaming_client/main.cpp
  • examples/apps/streaming_server/main.cpp

Authentication and Authorization Hooks

The SDK provides hooks for carrying credentials and auth metadata. Your application remains responsible for credential storage, verification, authorization decisions, and audit policy.

Client credential providers

include/a2a/client/auth.h includes providers for:

  • API key headers.
  • Bearer token headers.
  • Custom header credentials.
  • OAuth2 bearer token extension points.

Use these with transport call options or request construction paths that support metadata injection.

Server metadata

REST, JSON-RPC, and gRPC server paths populate RequestContext with transport metadata. Executor or interceptor code can read this metadata to make authorization decisions.

Policy guidance

  • Never hardcode secrets in source, examples, or tests.
  • Validate credentials before trusting request metadata.
  • Normalize auth failures so callers receive consistent protocol errors.
  • Avoid logging raw credentials.
  • Prefer short-lived tokens and managed secret storage.
  • Document how TLS or mTLS identity is terminated and propagated into the SDK boundary.

Example

See examples/apps/auth_policy_server/main.cpp for an auth-policy shape.

Releases and Versions

This documentation is intended to stay version-aware without embedding a release number in every page title.

Current documented release

The current documented release is v0.2.0. It includes:

  • REST, JSON-RPC, and gRPC client/server transport coverage.
  • Agent Card discovery, including extended Agent Card support.
  • Task lifecycle APIs including send, get, list, cancel, streaming send, and task subscription.
  • Task push-notification configuration APIs and server-side delivery abstractions.
  • Client and server interceptors.
  • CMake package exports and vcpkg-oriented packaging support.

Versioning guidance

  • Pin CMake FetchContent integrations to a release tag such as v0.2.0 or to a reviewed commit.
  • Prefer find_package(a2a_cpp CONFIG REQUIRED) for installed SDK packages.
  • Keep generated protobuf headers and linked SDK libraries from the same installed package or build tree.
  • Review release notes before upgrading between minor versions.

Documentation policy

Page titles and navigation should remain mostly version agnostic. Release-specific notes belong on this page or in clearly marked compatibility sections.

Build with CMake

a2a-cpp is a C++20 SDK built and packaged with CMake. The project can be used directly from source with FetchContent, installed into a CMake package prefix, or built with dependencies supplied by vcpkg.

Requirements

  • CMake 3.25 or newer.
  • A C++20 compiler.
  • Protobuf and gRPC development packages.
  • Optional: libcurl for the default buffered outbound HTTP implementation.
  • Optional: PostgreSQL client libraries when A2A_ENABLE_POSTGRES_STORE=ON.

On Ubuntu-like systems, the repository helper installs the dependencies used by CI:

./scripts/install_build_deps.sh

On macOS, install equivalent packages with Homebrew:

brew install cmake ninja protobuf grpc re2 abseil curl

Configure from source

The default source build enables tests, keeps the curated example apps out of the top-level build, and enables libcurl-backed HTTP support when CMake can find CURL::libcurl.

cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
  -DA2A_ENABLE_TESTING=ON

When dependencies are installed outside standard search paths, pass a CMake prefix path:

cmake -S . -B build \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DCMAKE_PREFIX_PATH="/opt/homebrew;/opt/homebrew/opt/curl"

Build and test

cmake --build build --parallel
ctest --test-dir build --output-on-failure

For the repository’s full local code validation flow, run:

./scripts/verify_changes.sh

That script runs the same main gates expected before a code PR: formatting, configure/build, tests, and clang-tidy.

CMake options

OptionDefaultDescription
A2A_ENABLE_TESTINGONBuilds unit and integration tests and enables CTest.
A2A_BUILD_EXAMPLESONCompatibility/message-only option for the root build today; curated examples are built as standalone consumers from examples/fetch_content_consumer or examples/installed_package_consumer.
A2A_BUILD_BENCHMARKSOFFBuilds benchmark targets under benchmarks/.
A2A_ENABLE_LIBCURLONEnables the default libcurl-backed outbound HTTP implementation when libcurl is found. Disable it to require injected requesters/fetchers.
A2A_ENABLE_POSTGRES_STOREOFFBuilds PostgreSQL-backed store targets when PostgreSQL dependencies are available.

Generated protobuf headers

The SDK generates A2A protocol C++ sources during the build. Primary generated A2A headers are written under build/generated/a2a/v1/, and generated Google API annotation headers are written under build/generated/google/api/.

Those generated headers are installed with the SDK, so downstream projects should include headers from the installed package rather than copying build-tree generated files.

Install as a CMake package

Install the SDK to a prefix:

cmake --install build --prefix /tmp/a2a-cpp-install

The install tree includes public headers, generated protobuf headers, libraries, and package configuration files under lib/cmake/a2a_cpp.

A downstream project can then consume the installed package:

cmake_minimum_required(VERSION 3.25)
project(my_a2a_app LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(a2a_cpp CONFIG REQUIRED)

add_executable(my_a2a_app main.cpp)
target_link_libraries(my_a2a_app PRIVATE a2a::client a2a::server a2a::core)

Configure that downstream project with CMAKE_PREFIX_PATH pointing at the install prefix:

cmake -S path/to/app -B build-app \
  -DCMAKE_PREFIX_PATH=/tmp/a2a-cpp-install
cmake --build build-app --parallel

FetchContent consumer

For application projects that prefer source integration, use CMake FetchContent and pin GIT_TAG to a release tag or reviewed commit:

include(FetchContent)

set(A2A_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
set(A2A_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(A2A_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE)
set(A2A_ENABLE_POSTGRES_STORE OFF CACHE BOOL "" FORCE)

FetchContent_Declare(
  a2a_cpp
  GIT_REPOSITORY https://github.com/MisterVVP/a2a-cpp.git
  GIT_TAG v0.2.0
)
FetchContent_MakeAvailable(a2a_cpp)

target_link_libraries(my_a2a_app PRIVATE a2a::client a2a::server a2a::core)

See examples/fetch_content_consumer/ for a minimal runnable consumer.

Exported targets

Common exported targets include:

  • a2a::core for shared core types and utilities.
  • a2a::client for client APIs.
  • a2a::server for server APIs.
  • a2a::http for HTTP support internals used by higher-level targets.
  • a2a::proto_generated for generated protobuf bindings.
  • a2a::store_postgres when PostgreSQL store support is enabled.

Most applications should link the smallest set they use. The examples link a2a::client, a2a::server, and a2a::core for a combined client/server sample.

Build the curated examples

Use the FetchContent example when testing source consumption:

cmake -S examples/fetch_content_consumer -B build-example \
  -DA2A_EXAMPLE_APP=hello_agent
cmake --build build-example --parallel
./build-example/a2a_example

Use the installed-package example when testing package consumption:

cmake -S examples/installed_package_consumer -B build-installed-example \
  -DCMAKE_PREFIX_PATH=/tmp/a2a-cpp-install \
  -DA2A_EXAMPLE_APP=hello_agent
cmake --build build-installed-example --parallel
./build-installed-example/a2a_example

Platform notes

  • Linux CI configures with CMake and validates build, tests, examples, clang-format, clang-tidy, coverage, and selected sanitizer/interop flows.
  • macOS CI builds with Homebrew-provided dependencies and Ninja.
  • Windows CI uses vcpkg manifest dependencies and the Visual Studio 2022 generator. See vcpkg for manifest, triplet, and overlay details.

Build with vcpkg

a2a-cpp provides vcpkg metadata for two related workflows:

  1. Manifest dependency mode for building this repository with vcpkg-supplied third-party dependencies.
  2. Overlay port mode for consuming a2a-cpp itself as a vcpkg package before it is available from a public registry.

The repository root vcpkg.json pins the dependency baseline and declares the SDK’s third-party dependencies: protobuf, gRPC, and curl.

Prerequisites

Install or clone vcpkg and bootstrap it:

git clone https://github.com/microsoft/vcpkg.git "$HOME/vcpkg"
"$HOME/vcpkg/bootstrap-vcpkg.sh"

On Windows PowerShell:

git clone https://github.com/microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat

Set VCPKG_ROOT for convenience:

export VCPKG_ROOT="$HOME/vcpkg"
$env:VCPKG_ROOT = 'C:\vcpkg'

Build this repository with manifest dependencies

From the repository root, let vcpkg install the manifest dependencies and then configure CMake with the vcpkg toolchain file:

"$VCPKG_ROOT/vcpkg" install
cmake -S . -B build-vcpkg \
  -DVCPKG_MANIFEST_MODE=ON \
  -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DA2A_ENABLE_TESTING=ON
cmake --build build-vcpkg --parallel
ctest --test-dir build-vcpkg --output-on-failure

On multi-config generators such as Visual Studio, pass the configuration during build and test:

& "$env:VCPKG_ROOT\vcpkg.exe" install
cmake -S . -B build-vcpkg -G "Visual Studio 17 2022" -A x64 `
  -DVCPKG_MANIFEST_MODE=ON `
  -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake"
cmake --build build-vcpkg --config RelWithDebInfo --parallel
ctest --test-dir build-vcpkg -C RelWithDebInfo --output-on-failure

Use a specific triplet

Pass the same target triplet to vcpkg and CMake. For native builds, use the same value for the host triplet so host tools such as protoc and grpc_cpp_plugin are resolved consistently:

"$VCPKG_ROOT/vcpkg" install --triplet x64-linux --host-triplet x64-linux
cmake -S . -B build-vcpkg \
  -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
  -DVCPKG_TARGET_TRIPLET=x64-linux \
  -DVCPKG_HOST_TRIPLET=x64-linux

Windows CI uses the repository triplet triplets/ci-x64-windows-release.cmake to build release-only dependencies and reduce dependency build time:

$env:VCPKG_OVERLAY_TRIPLETS = "$PWD\triplets"
& "$env:VCPKG_ROOT\vcpkg.exe" install --triplet ci-x64-windows-release --host-triplet ci-x64-windows-release
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
  -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
  -DVCPKG_TARGET_TRIPLET=ci-x64-windows-release `
  -DVCPKG_HOST_TRIPLET=ci-x64-windows-release

Consume a2a-cpp through the repository overlay port

The repository includes an overlay port at vcpkg-overlay-ports/a2a-cpp. A downstream manifest can depend on a2a-cpp and point vcpkg at that overlay.

vcpkg.json:

{
  "name": "my-a2a-app",
  "version-string": "0.2.0",
  "dependencies": [
    "a2a-cpp"
  ]
}

vcpkg-configuration.json:

{
  "default-registry": {
    "kind": "builtin",
    "baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
  },
  "overlay-ports": [
    "path/to/a2a-cpp/vcpkg-overlay-ports"
  ]
}

Then configure the application with the vcpkg toolchain file on the first CMake configure and use the installed CMake package:

find_package(a2a_cpp CONFIG REQUIRED)
target_link_libraries(my_a2a_app PRIVATE a2a::client a2a::server a2a::core)

A complete example is available in examples/installed_package_consumer/.

Enable PostgreSQL store support

The overlay port exposes a postgres-store feature. Enable it in manifest mode when your application needs PostgreSQL-backed stores:

{
  "name": "my-a2a-app",
  "version-string": "0.2.0",
  "dependencies": [
    {
      "name": "a2a-cpp",
      "features": ["postgres-store"]
    }
  ]
}

When the feature is enabled, link the additional target where needed:

target_link_libraries(my_a2a_app PRIVATE a2a::store_postgres)

Classic mode smoke install

For a direct overlay smoke test, run classic mode from a directory that does not contain a vcpkg.json manifest:

mkdir -p /tmp/a2a-vcpkg-smoke
cd /tmp/a2a-vcpkg-smoke
"$VCPKG_ROOT/vcpkg" install a2a-cpp --overlay-ports=/path/to/a2a-cpp/vcpkg-overlay-ports

Add a triplet if needed:

"$VCPKG_ROOT/vcpkg" install a2a-cpp:x64-linux --overlay-ports=/path/to/a2a-cpp/vcpkg-overlay-ports

Binary caching

Large dependencies such as gRPC and protobuf can take time to build. Enable binary caching for local and CI runs:

export VCPKG_BINARY_SOURCES="clear;files,$HOME/.cache/vcpkg-binary-cache,readwrite"
mkdir -p "$HOME/.cache/vcpkg-binary-cache"

On Windows PowerShell:

$env:VCPKG_BINARY_SOURCES = 'clear;files,C:\vcpkg-binary-cache,readwrite'
New-Item -ItemType Directory -Force C:\vcpkg-binary-cache | Out-Null

Troubleshooting

  • CMake cannot find gRPC or Protobuf: confirm CMAKE_TOOLCHAIN_FILE points to scripts/buildsystems/vcpkg.cmake before the first configure. If you configured without it, delete the build directory and configure again.
  • Unexpected manifest behavior in classic mode: classic vcpkg install a2a-cpp should be run outside directories containing vcpkg.json, otherwise vcpkg switches to manifest mode.
  • Different host and target triplets: pass both VCPKG_TARGET_TRIPLET and VCPKG_HOST_TRIPLET when cross-compiling or when CI uses a custom host triplet.
  • Slow clean builds: enable binary caching and prefer release-only dependency triplets for CI jobs that only link release configurations.

API Reference

The generated C++ API reference is built from public headers under include/a2a/**.

Generated reference

When published with the documentation site, open:

Generate locally

./scripts/generate_api_reference.sh

The script writes generated pages to book-build/api/cpp.

Public API areas

  • a2a::core: results, errors, protocol constants, JSON/protobuf helpers, Agent Card support, task state helpers, and versioning.
  • a2a::client: A2AClient, transports, discovery, auth hooks, call options, interceptors, and streaming observers.
  • a2a::server: executor, dispatcher, transports, interceptors, task stores, task lifecycle helpers, push notifications, and Agent Card serialization.
  • a2a::http: shared outbound HTTP client abstraction used by default REST/JSON-RPC/discovery/push paths when libcurl is enabled.