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.
Recommended reading path
- Installation and Build for toolchain requirements and CMake options.
- Quickstart for a copy/paste example flow.
- Client Overview or Server Overview, depending on your integration role.
- Transports, Streaming, and Authentication for runtime design decisions.
- 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-formatandclang-tidyfor 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:
| Option | Default | Purpose |
|---|---|---|
A2A_ENABLE_TESTING | ON | Builds unit and integration tests. |
A2A_BUILD_EXAMPLES | ON | Keeps the root project compatible with example-related CI messaging; curated examples are built as standalone consumers. |
A2A_BUILD_BENCHMARKS | OFF | Builds the optional Google Benchmark suite. |
A2A_ENABLE_LIBCURL | ON | Enables default buffered outbound HTTP when CURL::libcurl is found. |
A2A_ENABLE_POSTGRES_STORE | OFF | Builds 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
SendMessageGetTaskListTasksCancelTaskSendStreamingMessageSubscribeTaskCreateTaskPushNotificationConfigGetTaskPushNotificationConfigListTaskPushNotificationConfigsDeleteTaskPushNotificationConfig- Client interceptors via
ClientInterceptor - Per-call settings through
CallOptions
Typical flow
- Fetch an Agent Card with
DiscoveryClient. - Select an endpoint with
AgentCardResolver::SelectPreferredInterface. - Construct
HttpJsonTransport,JsonRpcTransport, orGrpcTransport. - Create
A2AClientwith the transport. - Invoke task, streaming, or push-notification APIs.
- 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.cppexamples/apps/simple_client/main.cppexamples/apps/streaming_client/main.cppexamples/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_idfor 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
CallOptionsfor 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.
Related pages
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::kRestPreferredTransport::kJsonRpcPreferredTransport::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.
Related files
include/a2a/client/discovery.hinclude/a2a/core/agent_card/agent_card_provider.hinclude/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
- Store the task ID from
SendMessageor a stream event. - Build
lf::a2a::v1::GetTaskRequest. - Call
A2AClient::GetTask. - Interpret task status, artifacts, and history according to your application policy.
ListTasks flow
a2a::client::ListTasksRequest contains:
page_sizepage_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.
Recommended behavior
- 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
- Implement an executor for task and message behavior.
- Create a
Dispatcherwith the executor and optional Agent Card provider/interceptors. - Attach REST, JSON-RPC, or gRPC transport adapters.
- Convert inbound framework requests into transport calls.
- 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:
SendMessageSendStreamingMessageGetTaskListTasksCancelTask
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, andparamsenvelope 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:
CreateTaskPushNotificationConfigGetTaskPushNotificationConfigListTaskPushNotificationConfigsDeleteTaskPushNotificationConfig
Use these only when the target Agent Card and server policy indicate push-notification support.
Server components
PushNotificationServicecoordinates stored configs and delivery.PushNotificationStorepersists webhook configs.PushNotificationDeliveryClientabstracts outbound delivery.HttpPushNotificationDeliveryClientprovides a simple libcurl-backed synchronous delivery path when libcurl support is enabled.
Recommended executor flow
- Persist task state in your
TaskStoreorTaskLifecycleService. - Register inline configs from
SendMessageRequestwhen present. - Call
NotifyTaskUpdated(task)after status changes. - Propagate delivery failures instead of silently dropping them.
- 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
AgentExecutorand cross-cutting behavior in interceptors.
Related APIs
a2a::server::ServerInterceptora2a::server::Dispatcher::AddInterceptora2a::client::ClientInterceptorfor 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
RequestContextonly 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::RpcClientfor 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:
SendMessageSendStreamingMessageGetTaskListTasksCancelTaskSubscribeToTask- 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.cppexamples/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
FetchContentintegrations to a release tag such asv0.2.0or 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
| Option | Default | Description |
|---|---|---|
A2A_ENABLE_TESTING | ON | Builds unit and integration tests and enables CTest. |
A2A_BUILD_EXAMPLES | ON | Compatibility/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_BENCHMARKS | OFF | Builds benchmark targets under benchmarks/. |
A2A_ENABLE_LIBCURL | ON | Enables the default libcurl-backed outbound HTTP implementation when libcurl is found. Disable it to require injected requesters/fetchers. |
A2A_ENABLE_POSTGRES_STORE | OFF | Builds 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::corefor shared core types and utilities.a2a::clientfor client APIs.a2a::serverfor server APIs.a2a::httpfor HTTP support internals used by higher-level targets.a2a::proto_generatedfor generated protobuf bindings.a2a::store_postgreswhen 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:
- Manifest dependency mode for building this repository with vcpkg-supplied third-party dependencies.
- Overlay port mode for consuming
a2a-cppitself 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_FILEpoints toscripts/buildsystems/vcpkg.cmakebefore 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-cppshould be run outside directories containingvcpkg.json, otherwise vcpkg switches to manifest mode. - Different host and target triplets: pass both
VCPKG_TARGET_TRIPLETandVCPKG_HOST_TRIPLETwhen 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.