MCP vs A2A: One Connects Tools, the Other Connects Agents
MCP and A2A are both agent protocols, but they solve different problems. Compare tool invocation with agent delegation using the same refund workflow, Agent Cards, Tasks, Artifacts, transports, and security boundaries.

Here is the shortest useful answer:
MCP lets an AI application use tools and data through a standard interface. A2A lets one agent delegate a goal to another agent and track the work.
Both may run over HTTP and exchange structured messages, but they operate at different abstraction layers. MCP exposes a concrete capability such as refund_order. A2A exposes an independent “refund specialist” that can plan, ask follow-up questions, use its own tools, report progress, and deliver artifacts.
The right question is not which protocol will replace the other. Ask instead: is the other side a tool, or an autonomous agent?
This article models the same refund workflow both ways and validates the objects with the official Python SDKs.
The core differences in one table
| Dimension | MCP | A2A |
|---|---|---|
| Full name | Model Context Protocol | Agent2Agent Protocol |
| Primary relationship | AI application ↔ tools, resources, and prompt templates | Client Agent ↔ Remote Agent |
| What the peer exposes | Tools, Resources, Prompts | Agent Card, Skills, Messages, Tasks, Artifacts |
| How transparent is the peer? | Schemas and protocol primitives are relatively explicit | The Remote Agent is normally treated as an opaque system |
| Unit of work | Operations such as tools/call and resources/read | A Message or a stateful Task |
| Typical duration | Often one concrete read or action, with progress support | Designed for immediate through long-running, asynchronous, multi-turn work |
| Discovery | tools/list, resources/list, prompts/list | Agent Card with Skills, interfaces, and security requirements |
| Result | Content, structured content, or resources | Message, status updates, and Artifacts |
| Common transport | stdio and Streamable HTTP | JSON-RPC, REST, or gRPC bindings over network transports; SSE can stream updates |
| Security focus | Tool permissions, input validation, local processes, prompt injection | Agent identity, authorization, cross-boundary delegation, task data, callbacks |
This table describes the center of gravity, not a hard limitation. An MCP Tool can perform complex work, and an A2A Agent can be simple. The practical distinction is whether you are requesting a defined capability or delegating an outcome.

MCP mental model: I know which operation to call
In the previous hands-on MCP introduction, we ran this sequence:
initialize
→ tools/list
→ tools/call
→ tool result
A Host discovers tools through an MCP Client and submits arguments that follow the advertised schema. For example:
{
"name": "refund_order",
"arguments": {
"order_id": "NB-2001",
"amount": 29.9
}
}
The caller has already decided to issue a refund and knows that the operation needs an order ID and amount. The Server validates, authorizes, and executes that concrete capability.
An MCP Server does not have to be an agent or call an LLM. It may simply adapt a payment API, database, or filesystem.
A2A mental model: I know the goal and delegate the process
An A2A Client Agent can send a goal such as:
Investigate refund case NB-2001. The customer reports a duplicate charge.
The Remote Agent advertises a “refund case investigation” Skill rather than forcing the caller to orchestrate every low-level step. Internally, it might:
- inspect the order and payment records;
- apply refund policy;
- check fraud signals;
- request missing evidence;
- invoke a payment tool;
- produce an auditable decision report.
From the Client Agent's perspective, the Remote Agent is a black box. The client cares about promised Skills, authentication, task state, and delivered Artifacts—not the remote model, framework, or private tools.
Real comparison: one refund workflow, two models
I exercised or serialized both models using the official Python SDKs:
- MCP Python SDK:
1.28.1 - A2A Python SDK:
1.1.1
The test uses fictional order NB-2001 and does not touch production data or a payment processor.

Option A: model the refund as an MCP Tool
Minimal MCP Server:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("payment-tools")
@mcp.tool()
def refund_order(order_id: str, amount: float) -> dict:
"""Issue a deterministic refund after application-level authorization."""
return {
"refund_id": "RF-2001",
"order_id": order_id,
"amount": amount,
"status": "succeeded",
}
if __name__ == "__main__":
mcp.run(transport="stdio")
After a real stdio initialization, tools/list discovered:
{
"sdk": "1.28.1",
"discovery": ["refund_order"]
}
The core content from the real call was:
{
"refund_id": "RF-2001",
"order_id": "NB-2001",
"amount": 29.9,
"status": "succeeded"
}
This model fits an operation with a clear boundary. The caller decides to refund 29.9, and the tool executes it. JSON Schema validates shape, not authority: the application still has to check who may issue refunds, the maximum amount, and idempotency.
Option B: model the case as an A2A Agent
A2A starts with an Agent Card describing the Remote Agent. This is the core card serialized by the official SDK probe:
{
"name": "Refund Specialist",
"description": "Investigates refund cases and returns a decision report.",
"supported_interfaces": [
{
"url": "https://refund.example/a2a",
"protocol_binding": "JSONRPC",
"protocol_version": "1.0"
}
],
"capabilities": {
"streaming": true,
"push_notifications": true
},
"skills": [
{
"id": "refund-case",
"name": "Refund case investigation",
"tags": ["refund", "billing"]
}
]
}
The URL is a non-routable example, not a live service. The Agent Card acts as a digital business card and tells a client:
- who the Agent is and which Skills it offers;
- which protocol interfaces and versions it supports;
- accepted input and output media types;
- whether streaming and push notifications are available;
- which security schemes are required.
The Client Agent sends a Message:
{
"message_id": "msg-102",
"context_id": "ctx-102",
"role": "ROLE_USER",
"parts": [
{
"text": "Investigate refund case NB-2001. Customer reports duplicate charge."
}
]
}
A Remote Agent can return a plain Message for an immediate answer. If the work needs state or follow-up interaction, it creates a Task. The probe's initial object was:
{
"id": "task-102",
"context_id": "ctx-102",
"status": {
"state": "TASK_STATE_SUBMITTED"
}
}
The same Task later reaches TASK_STATE_COMPLETED with an Artifact:
{
"id": "task-102",
"status": {
"state": "TASK_STATE_COMPLETED"
},
"artifacts": [
{
"artifact_id": "artifact-102",
"name": "refund-decision.json",
"parts": [
{
"data": {
"decision": "approve",
"amount": 29.9,
"reason": "duplicate_charge"
}
}
]
}
]
}
This is not a claim that a complete network server was deployed. It is an executable modeling probe that created and serialized an Agent Card, Message, Task, and Artifact with official a2a-sdk 1.1.1. It verifies the different delivery units: MCP returns a tool result; A2A manages delegated work and its artifacts.
Why A2A needs Tasks
Agent work is often not one function call. It may:
- take minutes or hours;
- require more evidence from a user;
- wait for authorization;
- emit partial results;
- outlive the client's current connection.
A2A therefore gives Task a defined lifecycle. Current states include:
submitted → working → completed
↘ failed
↘ canceled
↘ rejected
↘ input-required
↘ auth-required
input-required and auth-required are interrupted states rather than generic failures. They tell the Client what must happen before work can continue.
contextId groups related Messages and Tasks into one interaction context, while taskId identifies a particular unit of work. Follow-up requests can reference them for multi-turn collaboration.
MCP also supports progress and notifications, and the 2025-11-25 specification adds experimental Tasks for deferred execution and status tracking. Its center of gravity is still Client–Server capability exchange, however, and Tasks are not yet a universally stable feature across Clients and SDKs. A2A treats stateful cross-Agent delegation, human intervention, and asynchronous delivery as part of its core data model.
Discovery: a Tool Schema is not an Agent Card
MCP discovers concrete operations
tools/list returns:
- a tool name;
- description;
inputSchema;- optional
outputSchemaand annotations.
The caller receives a function-like contract.
A2A discovers a collaborator
An Agent Card describes:
- identity, version, and provider;
- supported protocol interfaces;
- capabilities;
- authentication and security requirements;
- input and output media types;
- Skills, examples, and tags.
A public card can be discovered through a well-known URI, while registries and direct private configuration suit other environments. Finding a card does not mean trusting its Agent. Production clients still need provenance, signature, domain, authentication, and policy checks.
Message, Task, and Artifact
| A2A object | Purpose | Refund example |
|---|---|---|
| Message | One turn between agents | “Investigate duplicate charge” or “Upload payment evidence” |
| Part | Content container inside a Message or Artifact | Text, file reference, bytes, or structured data |
| Task | A stateful unit of work with an ID and lifecycle | The refund investigation |
| Artifact | A tangible result produced by a Task | Decision report, receipt, or JSON conclusion |
Not every Message should become a Task. A self-contained immediate answer may remain stateless; a Task is useful when work needs tracking, asynchronous execution, or multiple turns.
Do not confuse their transports either
MCP
The standard transports are:
- stdio;
- Streamable HTTP.
They carry MCP's JSON-RPC lifecycle and primitives.
A2A
A2A 1.0 defines operations that can be exposed through declared interface bindings. The official ecosystem currently includes:
- JSON-RPC over HTTP;
- REST;
- gRPC.
Long-running work can use:
- request/response followed by Task polling;
- SSE streams for status and Artifact updates;
- Push Notification configuration when clients disconnect.
“They both use JSON-RPC” does not make them equivalent. HTTP and JSON-RPC are delivery mechanisms; the semantic models above them are different.
Security: A2A is not simply a larger Tool permission
MCP concerns
- confirming tool arguments and side effects;
- permissions of local Server processes;
- path, tenant, and business authorization;
- prompt injection in Tool or Resource content;
- authentication, Origin checks, and session security for remote Servers.
A2A concerns
- whether an Agent Card represents a trusted party;
- which user or service the Client Agent represents;
- which task data the Remote Agent may receive;
- whether cross-organization delegation is allowed;
- tenant isolation for history and Artifacts;
- authenticating SSE and Push Notification callbacks while preventing replay and SSRF;
- whether an Agent may delegate again or invoke high-impact tools.
A frequent mistake is to assume that because a Client Agent may read an order, every Remote Agent inherits that permission. Delegating a goal does not mean delegating all identity and credentials. Use scoped, auditable, revocable authorization rather than passing upstream tokens through.
Using MCP and A2A together

Real systems often use both:
User
↓
Support Agent
│
├── A2A → Refund Specialist Agent
│ ├── MCP → Order database
│ ├── MCP → Payment tool
│ └── MCP → Fraud check
│
└── A2A → Logistics Agent
└── MCP → Shipping API
A2A delegates “investigate this refund” to the specialist. Inside that specialist, MCP connects to order, payment, and fraud tools.
The model API is a third boundary. Each Agent may use OpenAI, Claude, Gemini, or another provider. Neither MCP nor A2A unifies model pricing, token accounting, or provider failover. That is where an AI API gateway such as Nbility fits when several Agents need one reliable model access layer.
Decision rules
Use MCP when you need to
- read a database, file, or API;
- invoke an operation with explicit arguments;
- reuse one tool across several Hosts;
- keep execution independent from the model provider;
- enforce fine-grained authorization per operation.
Use A2A when you need to
- delegate a goal to an independent Agent;
- hide the Remote Agent's internal implementation;
- track long-running or multi-turn work;
- exchange statuses, files, and structured deliverables;
- collaborate across teams, systems, or organizations.
Use neither when
- an ordinary function call is sufficient;
- everything lives in one process and one fixed workflow;
- identity, authorization, and audit controls do not exist yet;
- the extra protocol is there only because the topic is fashionable.
Five common misconceptions
1. “A2A is MCP 2.0”
No. A2A addresses delegation between Agents; MCP connects applications to tools and context. The official A2A documentation explicitly describes them as complementary.
2. “A2A eliminates the need for MCP”
A Remote Agent still needs databases, files, and business APIs. MCP remains a natural internal connection layer.
3. “Every MCP Server is an Agent”
No. A deterministic database adapter is a perfectly valid MCP Server. A peer looks more like an A2A Agent when it accepts goals, plans autonomously, and owns a task lifecycle.
4. “Every A2A interaction creates a Task”
No. A simple immediate interaction may return a stateless Message. Create a Task when the work needs tracking.
5. “An Agent Card is a trust certificate”
No. It is capability and connection metadata. Discovery must still be followed by authentication, authorization, provenance checks, and risk decisions.
Version note
At the time of verification:
- the official A2A site showed specification
v1.0.1; - the installed official Python SDK was
1.1.1; - the MCP probe used official Python SDK
1.28.1.
Both protocols and SDKs evolve quickly. Do not treat sample versions, interface URLs, or enums as permanent constants. Pin dependencies, read Agent Card and capability declarations, and maintain compatibility tests for upgrades.
Takeaway
Three questions usually settle the choice:
- Am I invoking a defined operation or delegating a goal?
- Do I need an immediate result or a tracked task with states and artifacts?
- Must I understand execution details, or only the peer's promised Skill and outcome?
The first side usually points to MCP, the second to A2A. Complex Agent systems often use both: A2A connects Agents horizontally, while MCP connects each Agent vertically to tools and data.
A model API gateway occupies a separate plane, giving those Agents unified model access, usage accounting, and provider reliability. Keeping all three layers distinct prevents “AI protocol” from becoming an architectural junk drawer.


