Cross-Protocol MCP + A2A Bridge Server: Connecting MCP Tools to A2A Agents for Enterprise Interop
Bridge Anthropic's MCP tool surface to Google/A2A's agent-to-agent task lifecycle: discovery via Agent Cards, task-state negotiation, and a single gateway that turns any MCP tool into a delegable A2A task for the enterprise.
Deepak Bagada
CEO, SaaSNext
- MCP and A2A are complementary: MCP covers tool invocation, A2A covers agent-to-agent delegation across vendors and frameworks.
- A cross-protocol bridge translates synchronous MCP tool calls into stateful A2A tasks tracked through the full lifecycle.
- Discovery via the Agent Card at /.well-known/agent-card.json and a allowlist make delegation secure and auditable.
Cross-Protocol MCP + A2A Bridge Server: Connecting MCP Tools to A2A Agents for Enterprise Interop
Two primitives dominate agent architecture in 2026, and they solve different problems. MCP (Model Context Protocol) standardizes how an agent talks to tools, data, and APIs — one client, many tools, JSON-RPC over stdio or HTTP. A2A (Agent2Agent Protocol, donated by Google and now a Linux Foundation project) standardizes how one agent talks to another — discovery, delegation, and a stateful task lifecycle across organizational boundaries.
The moment exactly your stack crosses a vend boundary — an AWS Bedrock AgentCore next to a Google Cloud agent, or an in-house agent delegating to a partner SaaS agent — MCP alone is not enough. You need a cross-protocol bridge server that translates a local MCP tool call into an A2A task the remote agent accepts, works, and replies to. That bridge is the enterprise interop layer this guide builds.
By Deepak Bagada, CEO at SaaSNext & Principal AI Architect.
Key insight: MCP and A2A are complementary, not rivals. MCP is the syntactic layer of tool invocation; A2A is the application-level layer of agent-to-agent messaging. A bridge connects them: your MCP tools become capabilities another agent can delegate.
Why bridge the protocols
Enterprises run agents on more than one platform. A2A was designed for exactly that: agents from different vendors discover each other's capabilities, negotiate modalities (text, files, structured JSON), manage shared tasks with an explicit lifecycle, and exchange results with zero requirement that two agents share memory, tools, or internal state. The protocol's momentum in its first year:
- 150+ supporting organizations under the Linux Foundation
- Official SDKs in Python, JavaScript, Java, Go, C#/.NET, and Rust
- Support in all three major clouds (GCP, Azure AI Foundry, AWS Bedrock AgentCore)
- An Agent Card served at
.well-known/agent-card.json(RFC 8615) - JSON-RPC 2.0 transport with SSE streaming and webhook push notifications
The bridge exists because most of an agent's real capability — the tools it can actually execute, such as an SQL check, a refund, a document write — lives on the MCP side. A cross-protocol gateway poses that capability as an A2A task a partner agent delegates to locally.
The two faces of the bridge
The protocols serve different purposes, and the union yields a clean division of labor:
| Dimension | MCP | A2A |
|---|---|---|
| Purpose | Agent to tool and data | Agent to agent |
| Scope | Local tool connections | Cross-org, cross-framework |
| Discovery | Static server config | Agent Card at .well-known/agent-card.json |
| Protocol | JSON-RPC (stdio / HTTP) | JSON-RPC 2.0 + SSE + webhooks |
| Task shape | Synchronous tool call | Async lifecycle (submitted, working, ...) |
| Identity | API keys / OAuth | OpenAPI-style bearer schemes |
| Typical use | Agent to SQL, RAG, APIs | Orchestrator delegates to specialist |
The bridge tools notifications: it exposes every registered A2A agent as MCP tool descriptors on the local orchestrator, and it forwards MCP tool-shaped work out as A2A tasks.
A2A task lifecycle
A2A is stateful where MCP is synchronous. A task is sorted into submitted, moves to working, can pause on input-required or auth-required, and terminates in completed, failed, canceled, or rejected:
submitted
|
v
working <-------- input-required (waiting for more data)
| | (resume to working)
| v
| auth-required
|
+---- completed / failed / canceled / rejected
A durable task store must back the lifecycle so a restart does not strand a working task in the middlestate.
[!NOTE] Key insight: A delegated task does not require the caller to know the remote agent's internal reasoning. The bridge tracks only state transitions and artifacts. That is what makes hierarchical delegation possible across organizations without access to another agent's memory.
Bridge architecture
A minimal production footprint:
+----------------------------------+
| Orchestrator agent (LangGraph, | calls MCP tools
| ADK, CrewAI) on an MCP client |
+---------------+-----------------+
|
| MCP (stdio / streamable HTTP)
v
+------------------------------+ A2A over JSON-RPC 2.0 + SSE
| Cross-Protocol Bridge |--------------------------+
| - MCP client + A2A client | |
| - durable TaskStore | v
| - Agent Card registry | +-----------------------------+
+------------------------------+ | Remote A2A agent |
| // receives tasks, |
| // streams states, dices |
+-----------------------------+
In this topology, an MCP-native orchestrator delegates work to a remote A2A agent through the bridge's A2A-first transport. Conversely, the bridge surfaces each registered A2A agent to your MCP client as tool descriptors the model can invoke.
A TypeScript bridge server
Using the official A2A SDK plus @modelcontextprotocol/sdk, the bridge is compact. The core delegate tool sends a task to a registered agent URL and returns the created A2A task you then poll.
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { A2AClient, TaskState } from '@google/a2a-sdk'
const server = new McpServer({ name: 'a2a-bridge', version: '1.0.0' })
const agents = new Map() // name -> A2AClient
server.tool(
'register_agent',
'Register an A2A agent by URL and load its Agent Card',
{
inputSchema: {
type: 'object',
properties: {
url: { type: 'string', description: 'Agent Card / A2A agent URL' },
name: { type: 'string', description: 'Logical name to reference' }
},
required: ['url', 'name']
} as any,
},
async ({ url, name }) => {
const client = new A2AClient(url)
const card = await client.agentCard()
agents.set(name, client)
return { content: [{ type: 'text', text: JSON.stringify(card, null, 2) }] }
}
)
server.tool(
'delegate_task',
'Delegate a task to an A2A agent and read the task state',
{
inputSchema: {
type: 'object',
properties: {
agent: { type: 'string', description: 'Registered agent name' },
goal: { type: 'string', description: 'Plain-language task instruction' },
task_id: { type: 'string', description: 'Optional caller-supplied ID' }
},
required: ['agent', 'goal']
}
},
async ({ agent, goal, task_id }) => {
const client = agents.get(agent)
if (!client) throw new Error('agent not registered')
const state = await client.send(task_id ?? crypto.randomUUID(), {
role: 'user',
message: { role: 'user', parts: [{ text: goal }] }
})
return { content: [{ type: 'text', text: JSON.stringify(state, null, 2) }] }
}
)
await server.connect(new StdioServerTransport())
Key insight: The orchestrator still thinks in tool calls; the remote agent thinks in tasks. The bridge does the translation and, with an SSE-backed client, the streaming — so the MCP caller sees familiar tool semantics while the A2A backend gets a real task lifecycle.
The Python FastMCP variant
For state-machine-heavy orchestration, a Python bridge keeps lifecycle accounting readable:
import asyncio
from fastmcp import FastMCP
from a2a import Client, TaskState
mcp = FastMCP("a2a-bridge")
registry: dict[str, Client] = {}
@mcp.tool()
def register(url: str, name: str) -> str:
'''Register an A2A agent from its URL and read its Agent Card.'''
cl = Client(url)
registry[name] = cl
return cl.agent_card().model_dump_json(indent=2)
@mcp.tool()
def delegate(agent: str, goal: str) -> str:
'''Delegate a task and wait for a terminal state.'''
cl = registry[agent]
state = asyncio.run(cl.send(goal))
while state.state not in {TaskState.COMPLETED, TaskState.FAILED,
TaskState.CANCELED, TaskState.REJECTED}:
if state.state == TaskState.INPUT_REQUIRED:
# pass control back through the MCP tool for clarification
state = asyncio.run(cl.send_message(state.id, {"text": "please continue"}))
else:
await asyncio.sleep(1)
state = asyncio.run(cl.get_task(state.id))
return state.model_dump_json(indent=2)
mcp.run(transport="streamable-http")
Both variants exercise real A2A behavior — discovery, state transitions, streaming, terminal outcomes — while remaining callsable from any MCP client.
Discovery via the Agent Card
The Agent Card is the connective tissue. Each A2A agent publishes one at a well-known path; the bridge reads it once and caches the advertised capabilities:
{
"name": "candidate-screener",
"description": "Screens job candidates against requirements",
"url": "https://screener.example.com/a2a",
"version": "1.0.0",
"capabilities": {
"supported_tasks": ["screen_candidate", "verify_credentials"],
"streaming": true,
"push_notifications": false
},
"authentication": {
"schemes": [{ "type": "bearer", "bearerFormat": "JWT" }]
},
"default_input_modalities": ["text"],
"default_output_modalities": ["text", "json"]
}
This is how the bridge decides whether to delegate: it checks supported_tasks against the requested goal instead of matching static skill strings.
Enterprise interop in practice
A partner-hosted candidate-screener agent receives a task from your orchestrator through the bridge, runs the A2A lifecycle (including input-required pauses to collect interview notes), and returns a structured result. The same bridge mediates the task through the three clouds and keeps the pattern stable as more SDKs ship. That is the enterprise play: one bridge, many protocol bindings, and an auditable task log end to end.
Deploy this alongside other server recipes from the MCP directory, compose it into larger workflow automation, and track protocol updates on our latest AI news.
Security across protocols
The delegation path widens your attack surface, so scope it explicitly:
- Identity. MCP carries API keys or OAuth for tool calls; A2A carries OpenAPI-compatible bearer schemes declared on the Agent Card. The bridge maps incoming MCP identity to an A2A principal without ever leaking a key.
- Discovery trust. Only auto-register agents from a curated allowlist of
.well-knowncards; validate card schema and the sender's issuer. - Capability scoping. Delegate tasks only thus match an agent's
supported_tasks; the bridge refuses out-of-scope work. - Audit. Log every lifecycle transition (submitted, working, input-required, terminal) so audits can prove a delegation chain end to end.
FAQ
Do I need the bridge if I run a single framework? No. If the orchestrator and its agents share one runtime, plain MCP tool calls are enough. The bridge pays off across vendor or framework boundaries where discovery, delegation, and a task lifecycle are required.
What are the A2A task states? A task moves submitted to working to a terminal of completed, failed, canceled, or rejected, with interrupt states input-required and auth-required that pause without ending. The bridge must track and resolve them.
Is A2A replacing MCP? No. They are complementary layers: MCP is the tool-call (syntactic) layer, A2A is the agent-to-agent (semantic) layer. A bridge joins them, and neither supersedes the other.
Can a remote A2A agent call my MCP tools in return? Directly, no; A2A only defines agent-to-agent tasks. Inverted, you establish a matching backhaul leg — associate a local MCP tool behind a delegated A2A task descriptor — but yes the caller never inherits your raw tools today.
Explore more MCP and agent integration guides in the MCP directory on Daily AI World, apply the patterns to your workflows, and stay current on the latest AI news.
By Deepak Bagada, CEO at SaaSNext & Principal AI Architect.
Enjoyed this breakdown? Get our morning dispatch in your inbox.
Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.
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.
Cursor 2026 Agent Mode & Google Workspace Plugins: Multi-File Automated Code Execution Architecture
Next Story →Google ADK in 2026: Enterprise Multi-Agent Systems with Native A2A Protocol & Multimodal Agents
Related Intelligence Analysis
Vercel AI SDK Tool Calling React: 5 Steps (2026)
Vercel AI SDK tool calling React integration is a programming pattern that executes server-side functions based on large language model decisions and streams the results to a React frontend. By combining streamText with...
Fact-Density vs. Word Count: The New SEO for 2026
Fact Density is the ratio of verifiable, unique information to the total word count of a piece of content. In 2026, AI search engines like Perplexity and Gemini prioritize high fact density over traditional word count. A...
NVIDIA Audex vs Qwen3.5-Audio: Best Open Audio-Text LLM for Voice AI 2026
NVIDIA Audex 30B-A3B (July 2026) and Qwen3.5-35B-A3B are the two leading open audio-text LLMs. Audex uniquely handles both audio understanding and generation in a single model while preserving text intelligence. Qwen3.5-...