Skip to content

A2A Protocol

A2A (Agent-to-Agent) is Google’s open protocol for agent interoperability. Atmosphere auto-registers A2A endpoints when the atmosphere-a2a module is on the classpath. Your @Agent becomes discoverable by any A2A-compatible agent or orchestrator.

Declares a skill that this agent exposes to other agents. Applied at the class level alongside @Agent or @ManagedService.

@Agent(name = "translator", headless = true)
@AgentSkill(
name = "translate",
description = "Translates text between languages",
tags = {"nlp", "translation"}
)
public class TranslatorAgent {
// ...
}

Marks a method as the handler for incoming A2A task requests. The method receives the task payload and returns a result.

@AgentSkillHandler
public TaskResult handleTranslation(
@AgentSkillParam("text") String text,
@AgentSkillParam("targetLanguage") String targetLanguage
) {
String translated = translationService.translate(text, targetLanguage);
return TaskResult.completed(translated);
}

Declares a parameter on an @AgentSkillHandler method. Parameters are exposed in the Agent Card’s skill definition and validated at runtime.

When atmosphere-a2a is on the classpath, Atmosphere publishes an Agent Card at /.well-known/agent.json. The card describes the agent’s identity, skills, and supported protocols.

{
"name": "translator",
"description": "Translates text between languages",
"url": "https://example.com/translator",
"version": "1.0.0",
"skills": [
{
"id": "translate",
"name": "translate",
"description": "Translates text between languages",
"tags": ["nlp", "translation"],
"parameters": {
"text": { "type": "string", "required": true },
"targetLanguage": { "type": "string", "required": true }
}
}
],
"protocols": ["a2a", "mcp"]
}

Other agents discover your agent by fetching this card. Orchestrators like Google ADK use it to determine which agents can handle which tasks.

A2A uses JSON-RPC 2.0 over HTTP. Atmosphere handles serialization, error mapping, and streaming responses automatically.

MethodDescription
tasks/sendSend a task to the agent and wait for completion
tasks/sendSubscribeSend a task and stream progress via SSE
tasks/getCheck the status of a previously submitted task
tasks/cancelCancel a running task

A2A is designed for agent-to-agent communication. Agents that only serve other agents should use headless = true:

@Agent(name = "data-enrichment", headless = true)
@AgentSkill(name = "enrich", description = "Enriches records with external data")
public class DataEnrichmentAgent {
@AgentSkillHandler
public TaskResult enrich(@AgentSkillParam("record") String recordJson) {
// enrich and return
}
}

Headless agents have no browser UI. They are reachable via A2A JSON-RPC, MCP (if on classpath), and programmatic API.

Protocol annotations are composable. An @Agent can expose @AgentSkill, @McpTool, and @AgUiEndpoint simultaneously — each protocol is served on its own endpoint, all backed by the same agent logic.