Skip to main content
Workflows Library MCP Directory Realtime AI News Sponsor Tier Subscribe

A2A + MCP Interoperability Gateway: Cross-Framework Agent Communication with Google ADK & LangGraph

Agents speak two protocols: MCP for tools and A2A for agents. This workflow builds a FastAPI interoperability gateway that bridges Google ADK and LangGraph, exposing A2A inbound while multiplexing shared MCP tool servers to both frameworks.

Deepak Bagada

Deepak Bagada

CEO, SaaSNext

Aug 07, 2026 Published
|
Aug 07, 2026 Updated
|
12 Minutes Reading Time
Core Takeaways for Founders & Builders
  • MCP solves agent-to-tool connectivity on A2A solves agent-to-agent collaboration; a gateway, not a single protocol, is needed for heterogeneous fleets.
  • Make the gateway an A2A endpoint and an MCP client simultaneously so ADK and LangGraph share one tool registry with zero per-framework glue.
  • Use stable task lifecycle states and idempotency keys to make cross-protocol handoffs survive timeouts, retries, and duplicate delegation.

A2A + MCP Interoperability Gateway: Cross-Framework Agent Communication with Google ADK & LangGraph

By Deepak Bagada, CEO at SaaSNext & Principal AI Architect.

The two-protocol reality of 2026 agents

Agentic systems today speak two different languages, and they are not mutually intelligible out of the box. MCP (Model Context Protocol), the Anthropic-originated standard now cared for by the Linux Foundation, is the lingua franca for agents talking to tools and data sources. A2A (Agent2Agent), the protocol Google launched and also donated to the Linux Foundation, is the lingua franca for agents talking to other agents.

The moment you try to build a heterogeneous fleet — a LangGraph agent on the research track, a Google ADK agent on the recommendation track, and a CrewAI agent on the writing track — you discover that MCP answers "where are my tools?" while A2A answers "who can finish this task?" They solve adjacent problems, and production systems need both, bridged by a gateway.

This article designs a production-grade A2A + MCP interoperability gateway that lets an ADK agent and a LangGraph agent discover each other, exchange shared task cards, and route to shared MCP tool servers, without either framework being rewritten.

Understanding the two standards

Aspect MCP (Model Context Protocol) A2A (Agent2Agent)
Solves Agent-to-tool connectivity Agent-to-agent collaboration
Core abstraction Resources, Tools, Prompts AgentCard, Task, Message, Artifact
Transport stdio, Streamable HTTP, SSE HTTP + JSON-RPC (streaming SRP)
Lifecycle Client connects to tool server Agent publishes card; client claims task
Use case Files, DBs, search APIs, cloud services Handoffs, chained reasoning, delegation

MCP is a client-server tool brokerage; A2A is a peer-to-peer task handoff protocol. The gateway in this project normalizes both so that an ADK agent can invoke a LangGraph agent through the same task-shaped interface it uses for its own agents, and both can sit in front of the same MCP tool servers.

Interoperability gateway architecture

            +--------------------------------------------------------------+
            | ADMIN / CLI / WEB U.I                                         |
            +------------------+-------------------------------------------+-
                               |
                               v
                +-------------------------------+
                |   INTEROP GATEWAY (FastAPI)   |
                |  - A2A server root (/a2a)     |
                |  - A2A client for upstream    |
                |  - MCP client (Streamable HTTP)|
                |  - Task lifecycle + transport |
                +----------+----------+---------+----------+---------------+
                           | A2A                 | A2A     | MCP client
                           v                     v         v
              +------------------------+   +-------------------+
              |  ADK AGENT (Google)     |   |  LangGraph agent |
              |  A2A support built-in   |   |  A2A adapter     |
              +------------------------+   +-------------------+
                                              |            |
                                              v            v
                                        +---------------------------------+
                                        |  MCP TOOL SERVERS (stdio/HTTP)   |
                                        |  - Slack MCP  - Arxiv MCP        |
                                        |  - DB MCP     - Search MCP       |
                                        +---------------------------------+

The gateway is deliberately model- and framework-neutral. It exposes A2A to inbound clients, talks A2A to the ADK agent, translates A2A tasks into execution inside a LangGraph workflow, and is itself an MCP client that hands shared tools to both agents. Every handoff is recorded as a task with a stable lifecycle so any of them can fault, timeout, or be cancelled without corrupting the others.

Project layout

interop/
├── .env
├── gateway/
│   ├── schemas.py
│   ├── mcp_client.py
│   └── a2a_server.py
├── agents/
│   ├── adk_agent.py
│   ├── langgraph_tools.py
│   └── langgraph_graph.py
├── main.py
└── requirements.txt

Environment configuration

# .env
A2A_ENDPOINT=https://api.example.com/a2a
AGENT_SERVICE_URL=https://internal.agents.example.com
MCP_FILE_SERVER=mcp://file-server.internal:9000
MCP_ARXIV_SERVER=http://mcp-arxiv.internal
GOOGLE_API_KEY=AIza...
OPENAI_API_KEY=sk-...
GATEWAY_API_KEY=gw-secret-123
LANGFUSE_HOST=https://cloud.langfuse.com
LOG_LEVEL=INFO

A2A task and message schemas

A2A centers on the Task object: an agent accepts a task, produces messages, and optionally yields artifacts. Validation is strict so the gateway never forwards malformed handoffs.

# gateway/schemas.py
from typing import Optional
from pydantic import BaseModel, Field
from enum import Enum

class TaskState(str, Enum):
    SUBMITTED = "submitted"
    WORKING = "working"
    INPUT_REQUIRED = "input-required"
    COMPLETED = "completed"
    CANCELED = "canceled"
    FAILED = "failed"

class MessageRole(str, Enum):
    USER = "user"
    AGENT = "agent"

class TaskMessage(BaseModel):
    role: TaskRole = TaskRole.AGENT
    parts: list[dict] = Field(default_factory=list)

class Task(BaseModel):
    id: str
    session_id: str
    agent_id: str
    state: TaskState = TaskState.SUBMITTED
    messages: list[TaskMessage] = Field(default_factory=list)
    artifacts: list[str] = Field(default_factory=list)

MCP client that both agents share

MCP streamable HTTP keeps a stable session with the tool servers. The gateway owns these sessions and multiplexes them to ADK and LangGraph, so both agents transparently see the same tool universe.

# gateway/mcp.py
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def connect(server_url: str, headers: dict):
    async with streamablehttp_client(server_url, headers=headers) as (read, write, get_session_id):
        async with ClientSession(read, write, get_session_id, headers=headers) as session:
            await session.initialize()
            tools = await session.list_tools()
            return {t.name: t for t in tools.tools}

mcp list over each configured server URL registers the union of tools. Both the ADK agent and the LangGraph node route to this shared registry, which means tool additions at one MCP server propagate to every framework in the fleet with zero per-framework glue.

Google ADK agent with built-in A2A

Google's Agent Development Kit ships with an A2A server adapter out of the box, which is why ADK is the reference end of this gateway. The agent subscribes to MCP tools through ADK's McpToolset.

# agents/adk_agent.py
from google.adk.agents import LlmAgent
from google.adk.tools import mcp_toolset
from google.adk.sessions import InMemorySessionService

adk_agent = LlmAgent(
    name="recommender",
    model="gemini-2.5-pro",
    instruction="You return ranked finance recommendations. Delegate research via A2A.",
    tools=mcp_toolset.McpToolset(
        tools=[
            mcp_toolset.StreamableHttpMcpTool("TrendRank", "http://mcp-trends:9000"),
        ]
    ),
    session_service=InMemorySessionService(),
)

The A2A server adapter in ADK publishes an AgentCard so the gateway and the LangGraph agent can discover recommender as a capable peer. No custom A2A JSON-RPC boilerplate is required on the ADK side; the SDK handles the transport.

The gateway receives a task and fans out

# agents/langgraph.py
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver

def build_langgraph(state):
    g = StateGraph(dict)
    g.add_node("research", research_node)
    g.add_node("recommend", recommend_node)
    g.add_node("synthesize", synthesize_node)
    g.add_edge(START, "research")
    g.add_edge("research", "recommend")
    g.add_edge("recommend", "synthesize")
    g.add_edge("synthesize", END)
    return g.compile(checkpointer=MemorySaver())

The gateway maps an A2A Task onto the graph: it invokes graph.ainvoke(state, config={"thread_id": task.id}), streams astream_events back as A2A TaskMessages, and closes the task as COMPLETED when the final update lands. A2A is transport, LangGraph is execution — the gateway is the translator that keeps them decoupled.

Retry rules and error handling

Cross-protocol failures have a third class beyond typical service faults: translation failures, where an A2A artifact cannot be mapped to a LangGraph state field, or an MCP tool result cannot be encoded back into an A2A artifact.

# gateway/a2a_server.py
import asyncio
from typing import Optional

async def run_task_with_retry(task: Task, executor, max_attempts: int = 4) -> Task:
    for attempt in range(max_attempts):
        state_ = task.state.value
        if state_ in (TaskState.COMPLETED.value, TaskState.CANCELED.value):
            return task
        if state_ == TaskState.FAILED.value and attempt == max_attempts - 1:
            raise task.latest_exception
        try:
            result = await asyncio.wait_for(executor(task), timeout=90)
            task.state = TaskState.COMPLETED
            return task
        except asyncio.TimeoutError:
            task.state = TaskState.SUBMITTED
        except TranslationError:
            task.state = TaskState.INPUT_REQUIRED
        except ModelError as exc:
            task.state = TaskState.FAILED
            task.latest_exception = exc
    return task
Failure A2A state Strategy
Tool timeout (>90s) resubmit Retry with+1 attempt on a fresh thread
Artifact/state mismatch INPUT_REQUIRED Ask the source agent for a structured artifact
MCP server down FAILED Circuit-breaker 30s, then fail the peer task
Duplicate delegation dedup by task id Idempotency keys on the gateway

Everything is idempotent: tasks carry stable IDs, and the gateway holds a task ledger so replays do not double-execute side effects such as writes or notifications.

A2A vs MCP: which to add first

Need Protocol When to adopt
Call a database, API, or file server MCP Immediately
Chain two LLM agents built in different frameworks A2A As soon as you have 2+ agents
Let a third-party agent call our tools MCP server Turnkey integrations
Let a third-party agent delegate work to us A2A server Open a fleet

From gateway to durable execution

Now that the A2A/MCP gateway gives you clean cross-framework transport, the last missing capability is durability. Continue this journey in event-sourced durable agent execution with checkpointing to make every handoff resumable across crashes. You can also audit the growing MCP server directory to find the tool servers worth wiring into the gateway, and keep an eye on the latest agent protocol news for A2A and MCP spec releases.

Key takeaways

A gateway researched around A2A for task handoff and MCP for tool access decouples your fleet from any one framework. ADK and LangGraph remain first-class citizens; the gateway is the only component that knows both protocols, which keeps the rest of your stack simple and portable.

  1. Adopt MCP for tools, A2A for agents, and a gateway for translation — do not try to force one protocol to do the other's job.
  2. Pipe every task through a stable lifecycle (submitted -> working -> completed | failed | canceled) so timeouts and retries are deterministic.
  3. Make the gateway an MCP client and an A2A endpoint at the same time, so both ADK and LangGraph share one tool registry.

By Deepak Bagada, CEO at SaaSNext & Principal AI Architect.

Executive Briefing

Enjoyed this breakdown? Get our morning dispatch in your inbox.

Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.

Frequently Asked Questions
MCP (Model Context Protocol) standardizes how agents connect to tools, resources, and data sources. A2A (Agent2Agent) standardizes how agents discover and delegate tasks to other agents. MCP is client-server tool brokerage while A2A is peer-to-peer task handoff.
Yes. Google's Agent Development Kit ships with A2A server adapters and MCP tool support, so ADK agents can expose an AgentCard, interoperate over A2A JSON-RPC, and consume shared MCP tool servers without bespoke transport code.
Build a gateway that translates inbound A2A task messages into LangGraph invocations. Map an A2A Task to a graph thread, stream astream_events back as A2A TaskMessages, and close the task as completed when the final update lands.
Add MCP first for tool integration and database/API access, then A2A once you have two or more agents in different frameworks that must delegate work to one another. Both are interop standards now governed by the Linux Foundation.
Deepak Bagada
Author Profile

Deepak Bagada

CEO, SaaSNext

Deepak Bagada is the CEO of SaaSNext and founder of Daily AI World. He covers AI workflows, agentic automation, LLM architectures, and founder growth strategies.

Related Intelligence Analysis

Research Breakdown AI Workflows

The Step-by-Step Guide to Automating Meeting Tasks with Whisper

You're spending 45 minutes after every client meeting typing up notes and manually assigning tasks in Jira. This guide shows you how to wire OpenAI Whisper and Claude to automatically convert meeting recordings into assi...

Deepak Bagada Deepak Bagada
9m read
Research Breakdown AI Workflows

Lovable AI UI-to-Code Pipeline: 2026 Tutorial

Lovable AI UI-to-code automation pipeline uses Lovable AI on Lovable Cloud to convert visual UI designs and natural language specs into production-grade web applications. UI/UX designers and frontend developers bridging...

Deepak Bagada Deepak Bagada
8m read
Breaking AI Workflows

Claude Code's New Browser: 5 Workflows That Save Hours Daily

Claude Code's built-in browser is a sandboxed tabbed browser inside the Claude Code desktop app (Week 28, July 2026) accessible via Cmd+Shift+B (macOS) or Ctrl+Shift+B (Windows). It lets Claude open websites, read docume...

Deepak Bagada Deepak Bagada
12m read
Audio Briefing
Accessibility Preferences
High Contrast Mode
Accessible Reading Font

Keyboard Shortcuts

Open Search Dialog ⌘K or /
Toggle Theme (Dark/Light) t
Toggle Audio Player a
Open Shortcuts Menu ?
Close Active Dialog Esc