agent-card.yaml. Harnest mounts only the bindings declared by the compiled card; you do not implement A2A route handlers.
agent-card.yaml
/support/a2a in this example, becomes the mounted route. Use the public deployment URL in the Agent Card, then serve from the agent folder:
GET /.well-known/agent-card.json. Use JSONRPC instead of HTTP+JSON when that binding fits the client ecosystem better. Author A2A 1.0 for new integrations; Harnest also accepts protocol version 0.3 for compatibility on these two HTTP bindings.
Test the HTTP+JSON binding at the exact path declared by the card:
Understand when a Task exists
Harnest supplies
GetTask, filtered ListTasks, CancelTask, and explicit Task subscriptions. These operations are part of the mounted adapter, but callers use them only when their workflow needs Task state.
Persist A2A Tasks
Register a built-in Harnest store for both session and checkpoint responsibilities when A2A Tasks must survive a restart:
@task work, register an explicit @lifecycle.storage.tasks provider. Sessions and checkpoints do not implicitly configure queued work. PostgreSQL, Redis, and custom providers can persist the queue; see Task and cron storage. Recurring work also requires the same provider under @lifecycle.storage.cron.
An unfinished @task awaited inside @tool(durable=True) shares the Harnest run and continuation represented by its A2A Task. On GetTask or subscription, Harnest reconciles a durable result without replaying the original tool call.
The A2A contextId maps to the Harnest session ID. A text-input root accepts A2A text parts; a typed-input root requires exactly one structured data part. Harnest projects customer-visible text and structured results back to A2A parts while keeping tool arguments and results inside the executing agent boundary regardless of tool_activity. With OutputPolicy(thinking=True), a streaming Task emits provider-exposed reasoning as a working-status message whose metadata.harnest.type is thinking; reasoning is otherwise suppressed. Agent and graph-node lifecycle updates use the same working status with metadata.harnest.type: agent_activity; model metadata uses metadata.harnest.type: agent_metadata. Set agent_metadata=AgentMetadataMode.SUPPRESS to omit those updates and aggregate token counts from the final Message or Task artifact. Answer artifacts can carry metadata.harnest.agent attribution. With OutputPolicy(decision_results=True), streaming tasks also publish working-status metadata with metadata.harnest.type: decision_result and the typed decision in metadata.harnest.value. Decision results are hidden by default.
When OutputPolicy(agent_metadata=AgentMetadataMode.RAW) is enabled, streaming metadata updates
also carry the native ADK or LangGraph raw mapping. A remote A2A task store or
consumer may retain those values. Keep the normalized default unless every A2A
caller is authorized to receive provider metadata.
CancelTask reports success only after Harnest has made the owned run and continuation terminal. For a queued @task, cancellation also invalidates its execution lease and removes its private payload in task storage before committing the A2A CANCELED snapshot. Cancellation cannot undo external side effects already performed by the task.
Apply security and protocol limits
A2A routes use the root authentication pipeline. Security requirements inagent-card.yaml advertise the contract; an @lifecycle.authenticate extension enforces it. Agent Card discovery remains public. Task IDs are scoped to the compiled application and authenticated user; another user receives 404 rather than task-existence information.
Harnest does not currently serve gRPC bindings, push notifications, extended Agent Cards, or A2A extensions. Server startup rejects a card that asks the runtime to claim unsupported behavior.
Call this agent from Harnest
Use the lazy client directly or compose the endpoint as a portable remote agent.