Skip to content

Epic: A2A Protocol Integration — Multi-Agent Communication #48

@rbadillap

Description

@rbadillap

Objective

Enable Syner OS to communicate with external AI agents (Claude Code, Gemini CLI, custom agents) using the Agent-to-Agent (A2A) protocol, and expose Syner as a consumable A2A agent.

Context

Syner OS is an orchestrator agent. It plans, reasons, and coordinates — but today it operates as a single-agent system limited to its own context window and tools. To fulfill its role as an agentic operating system, Syner needs to delegate work to specialized agents and receive work from other orchestrators.

The A2A protocol (Google, now Linux Foundation) is the converging standard for agent-to-agent communication. It merged with IBM's ACP (Agent Communication Protocol) in Sep 2025, and both MCP (Anthropic) and A2A were donated to the Agentic AI Foundation (Linux Foundation) in Dec 2025. Backed by Google, IBM, Microsoft, AWS, Anthropic, Salesforce, and SAP.

How A2A and MCP work together

MCP  = vertical (agent <-> tools below it)       -> "what an agent can DO"
A2A  = horizontal (agent <-> agent at same level) -> "how agents TALK to each other"
                         +----------------+
                         |    Syner OS    |
                         | (orchestrator) |
                         +-------+--------+
                                 |
                     +-----------+-----------+
                     |                       |
                    A2A                     MCP
             "talk to agents"        "use tools"
                     |                       |
             +-------+-------+       +-------+-------+
             |       |       |       |       |       |
          Claude  Gemini  Custom   GitHub  Redis  Filesystem
          Code    CLI     Agents   API     Cache   Tools

Both use JSON-RPC 2.0 and are complementary, not competing.

Prior art

This supersedes #17 (closed), which explored agent communication before A2A existed as a standard. The approach has evolved from custom prompts to an open protocol.

Research

Full analysis available in the repo:

  • VIABILITY.md — Technical viability assessment (HIGH)
  • IMPACT.md — Impact analysis (HIGH — strategic enabler)

Key findings

  • Syner's architecture already aligns with A2A concepts:
    • AGENT.md -> A2A Agent Card
    • SKILL.md skills -> Agent Card skills[]
    • Workflow<T>.run() -> tasks/send
    • OrchestratorWorkers<T> -> Task delegation pattern
    • Registry<T> -> Agent discovery
    • runs/protocol (Status, Cancel, Retry) -> A2A task state machine
  • Official TypeScript SDK exists: @a2a-js/sdk (spec v0.3.0)
  • A2A-MCP bridges already exist for Claude Code integration
  • No architectural redesign needed — A2A is a new transport layer on existing primitives

Scope

Phase 1 — A2A Client (Syner delegates to external agents)

  • Add @a2a-js/sdk dependency
  • Implement A2A client in packages/sdk/src/system/a2a/client.ts
    • discoverAgent(url) — fetch /.well-known/agent-card.json
    • sendTask(agentUrl, message)tasks/send via JSON-RPC
    • getTaskResult(taskId)tasks/get for async results
    • streamTask(agentUrl, message)tasks/sendSubscribe via SSE
    • cancelTask(taskId)tasks/cancel
  • Extend OrchestratorWorkers<T> to support A2A agents as workers
  • Add A2A delegation tools to the skill system (SKILL.md + tools/)
  • Integration test: Syner -> Claude Code (via A2A-MCP bridge) or test A2A agent

Phase 2 — A2A Server (Syner as a consumable agent)

  • Generate Agent Card from AGENT.md + SKILL.md metadata
  • Expose /.well-known/agent-card.json in apps/os/
  • Implement JSON-RPC endpoint at apps/os/app/api/a2a/route.ts
    • Handle tasks/send, tasks/get, tasks/cancel
    • Support SSE streaming for tasks/sendSubscribe
  • Task state machine: submitted -> working -> input-required -> completed -> failed
  • Leverage existing runs/protocol (Status, Cancel, Retry, Approval) for task lifecycle

Phase 3 — Agent Registry

  • Implement agent registry in packages/sdk/src/system/registry/
    • Register/unregister A2A agents
    • Store Agent Cards with capabilities, skills, auth config
    • Health checks and availability tracking
  • Agent discovery: scan known URLs, fetch Agent Cards
  • Extend agents.json config to include A2A agent definitions
  • Cost/quality metadata per agent for intelligent routing

Phase 4 — Visual Orchestration UI (future)

  • Real-time view of agent delegation in apps/os/
  • Task state visualization (submitted -> working -> completed)
  • Agent network graph (who talks to whom)
  • Approval UI for human-in-the-loop delegation decisions

Out of Scope

  • Building custom A2A agents (separate repos/extensions)
  • ACP (Zed's Agent Client Protocol) — different layer (human -> agent in editors)
  • Claude Agent Teams — proprietary, Claude-only coordination
  • Replacing MCP — A2A complements MCP, does not replace it

Technical Details

A2A Protocol Core Concepts

Concept Description
Agent Card JSON at /.well-known/agent-card.json describing capabilities, skills, auth, endpoint
Task Unit of work. Stateful: submitted -> working -> input-required -> completed -> failed
Message Atomic communication unit, associated with a task
Artifact Output from task execution (text, structured data, files)
Transport JSON-RPC 2.0 over HTTPS, SSE for streaming

Architecture mapping

Syner Concept              ->  A2A Concept
------------------------------------------------------
AGENT.md metadata          ->  Agent Card
SKILL.md skills            ->  Agent Card skills[]
Workflow<T>.run()          ->  tasks/send
OrchestratorWorkers<T>     ->  Task delegation pattern
Registry<T>                ->  Agent discovery
runs/protocol Status       ->  Task state machine
runs/protocol Cancel       ->  tasks/cancel
runs/protocol Approval     ->  input-required state
mcp-server.ts (empty stub) ->  MCP server for tool exposure

Example flow: Syner delegates coding to Claude Code

1. Syner receives: "Add OAuth to the project"
2. Syner plans via OrchestratorWorkers (planner step)
3. Syner discovers Claude Code agent via registry
4. Syner sends A2A task: tasks/send -> Claude Code
5. Claude Code works (uses MCP internally for file access)
6. Claude Code responds: task completed + artifacts
7. Syner validates result (reads files via MCP, runs checks)
8. Syner synthesizes final response to user

File structure (proposed)

packages/sdk/src/system/a2a/
├── client.ts          # A2A client (discover, send, get, stream, cancel)
├── server.ts          # A2A server handler (JSON-RPC endpoint logic)
├── agent-card.ts      # Generate Agent Card from AGENT.md + SKILL.md
├── task.ts            # Task state machine
├── types.ts           # A2A TypeScript types (or re-export from @a2a-js/sdk)
├── SKILL.md           # A2A skill metadata
├── tools/
│   ├── delegate.ts    # delegate() tool - send task to an A2A agent
│   ├── discover.ts    # discover() tool - find available agents
│   └── index.ts
└── index.ts

apps/os/app/
├── .well-known/
│   └── agent-card.json/route.ts   # Dynamic Agent Card endpoint
└── api/a2a/
    └── route.ts                   # JSON-RPC A2A endpoint

Dependencies

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions