A2A Protocol
Caged supports the A2A (Agent2Agent) Protocol — a Linux Foundation standard (April 2026) for secure agent-to-agent delegation. While MCP connects agents to tools inside a sandbox, A2A connects agents to agents across sandboxes and organizations.
A2A vs MCP: When to Use Which
| Protocol | Purpose | Scope | Use Case |
|---|---|---|---|
| MCP | Agent → Tools | Inside sandbox | File ops, terminal, Git, databases |
| A2A | Agent → Agent | Across sandboxes | Delegation, collaboration, pipelines |
Think of it this way:
- MCP: "I need to read a file" → MCP tool in your sandbox
- A2A: "I need a Python expert to analyze this" → Delegate to Python analysis agent
Quick Start
1. Register Your Agent
Make your agent discoverable via A2A:
# Register an agent backed by a pipeline
caged a2a agents create \
--name "Code Analyzer" \
--description "Analyzes code for security vulnerabilities" \
--pipeline-id pipe_abc123 \
--public
2. Discover Remote Agents
Fetch another agent's capabilities:
caged a2a discover https://agent.example.com
Output:
Name: Security Auditor
URL: https://agent.example.com
Skills:
- code-review: Reviews code for security issues
- dependency-audit: Scans dependencies for CVEs
3. Delegate a Task
Send work to a remote agent:
caged a2a delegate https://agent.example.com \
--skill code-review \
--input '{"repo": "https://github.com/org/repo"}'
Core Concepts
Agent Card
Every A2A agent publishes an Agent Card at /.well-known/agent.json:
{
"name": "Code Analyzer",
"description": "Analyzes code for security vulnerabilities",
"url": "https://my-agent.caged.dev",
"version": "1.0.0",
"capabilities": ["streaming", "push"],
"skills": [
{
"id": "analyze",
"name": "Code Analysis",
"description": "Performs static analysis on code",
"tags": ["security", "static-analysis"],
"inputSchema": {
"type": "object",
"properties": {
"repo": { "type": "string" },
"branch": { "type": "string", "default": "main" }
},
"required": ["repo"]
}
}
],
"authentication": {
"type": "bearer",
"schemes": ["api_key"]
}
}
Task Lifecycle
Tasks flow through these states:
stateDiagram-v2
[*] --> pending
pending --> running: Agent accepts
running --> completed: Success
running --> failed: Error
running --> canceled: User/timeout
running --> input_needed: Needs clarification
input_needed --> running: User responds
completed --> [*]
failed --> [*]
canceled --> [*]
Skills
Skills are specific capabilities an agent offers. Each skill:
- Has an ID, name, and description
- Defines input/output schemas
- Can have tags for discovery
Integration with Pipelines
A2A delegation integrates directly with Caged pipelines via the a2a stage type:
name: Security Review Pipeline
stages:
- name: clone
type: command
command: git clone $REPO_URL ./code
- name: security-analysis
type: a2a
agent_url: https://security-agent.caged.dev
skill_id: analyze
input_from_state: [repo_url]
output_to_state: [findings]
max_cost_usd: 5.00
depends_on: [clone]
- name: report
type: command
command: ./generate-report.sh
depends_on: [security-analysis]
A2A Stage Configuration
interface A2AConfig {
agent_url: string; // Remote agent URL
agent_id?: string; // Specific agent ID (if multiple)
skill_id?: string; // Skill to invoke
prompt?: string; // Natural language prompt
input?: object; // Direct input data
priority?: number; // 1-10, higher = more urgent
max_cost_usd?: number; // Budget cap for this task
input_from_state?: string[]; // Pull from pipeline state
output_to_state?: string[]; // Push results to state
streaming?: boolean; // Enable SSE streaming
fallback_agent?: string; // Agent to try on failure
}
API Reference
Agent Registration
POST /v1/a2a/agents
Authorization: Bearer <api_key>
{
"name": "My Agent",
"description": "Does amazing things",
"pipeline_id": "pipe_abc123",
"skills": [...],
"public": true,
"max_cost_per_task": 10.00,
"rate_limit_rpm": 60
}
Task Creation
POST /v1/a2a/agents/{agentId}/tasks
Authorization: Bearer <api_key>
{
"skill_id": "analyze",
"input": { "repo": "https://github.com/org/repo" },
"priority": 5
}
Task Streaming (SSE)
GET /v1/a2a/tasks/{taskId}/stream
Accept: text/event-stream
Authorization: Bearer <api_key>
Events:
event: progress
data: {"percentage": 50, "message": "Analyzing dependencies..."}
event: message
data: {"role": "agent", "parts": [{"type": "text", "text": "Found 3 issues"}]}
event: complete
data: {"status": "completed", "output": {...}}
CLI Commands
# Agent management
caged a2a agents list
caged a2a agents create --name "..." --pipeline-id pipe_...
caged a2a agents get <agent-id>
caged a2a agents delete <agent-id>
caged a2a agents enable <agent-id>
caged a2a agents disable <agent-id>
# Discovery
caged a2a discover <url>
# Task delegation
caged a2a delegate <url> --skill <skill-id> --input '{...}'
caged a2a task get <url> <task-id>
caged a2a task cancel <url> <task-id>
caged a2a task message <url> <task-id> "Your response"
MCP Tools for A2A
When using Caged via MCP (Claude Desktop, Cursor, etc.), these tools are available:
| Tool | Description |
|---|---|
a2a_agents_list |
List your registered A2A agents |
a2a_agent_get |
Get agent details |
a2a_agent_create |
Register a new agent |
a2a_agent_delete |
Delete an agent |
a2a_discover |
Discover a remote agent |
a2a_delegate |
Delegate a task |
a2a_task_get |
Get task status |
a2a_task_message |
Send message to task |
a2a_task_cancel |
Cancel a task |
Security Considerations
Authentication
A2A in Caged uses Bearer token authentication:
- Each registered agent can have its own API key
- Tasks are authenticated and tracked per account
- Rate limits apply per-agent
Cost Controls
- Set
max_cost_per_taskon agent registration - Pipeline A2A stages can set
max_cost_usdper stage - Budget alerts integrate with existing notification channels
Trust
- A2A tasks contribute to trust scoring
- High-risk delegations may require approval (via HITL)
- All A2A activity is logged in the event stream
Example: Multi-Agent Code Review
A pipeline that orchestrates multiple specialized agents:
name: Comprehensive Code Review
triggers:
- type: github_pr
events: [opened, synchronize]
stages:
- name: fetch
type: command
command: git fetch origin $PR_HEAD && git checkout $PR_HEAD
- name: lint
type: a2a
agent_url: https://lint-agent.caged.dev
skill_id: lint-code
input: { language: "typescript" }
output_to_state: [lint_issues]
depends_on: [fetch]
- name: security
type: a2a
agent_url: https://security-agent.caged.dev
skill_id: scan
input_from_state: [changed_files]
output_to_state: [security_findings]
depends_on: [fetch]
- name: test-coverage
type: a2a
agent_url: https://test-agent.caged.dev
skill_id: analyze-coverage
output_to_state: [coverage_report]
depends_on: [fetch]
- name: summarize
type: llm
prompt: |
Summarize the code review findings:
- Lint issues: $lint_issues
- Security findings: $security_findings
- Coverage: $coverage_report
depends_on: [lint, security, test-coverage]
- name: comment
type: command
command: gh pr comment $PR_NUMBER --body "$summary"
depends_on: [summarize]
Best Practices
- Define clear skill boundaries — Each skill should do one thing well
- Version your agents — Include version in Agent Card for compatibility
- Set cost limits — Always specify
max_cost_per_taskand stage budgets - Use streaming for long tasks — Gives real-time progress feedback
- Implement fallbacks — Use
fallback_agentfor resilience - Tag skills appropriately — Helps with discovery and routing