MCPA2AAgent2AgentAI AgentMulti-AgentTool CallingNbility

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.

MCP vs A2A: One Connects Tools, the Other Connects Agents

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

DimensionMCPA2A
Full nameModel Context ProtocolAgent2Agent Protocol
Primary relationshipAI application ↔ tools, resources, and prompt templatesClient Agent ↔ Remote Agent
What the peer exposesTools, Resources, PromptsAgent Card, Skills, Messages, Tasks, Artifacts
How transparent is the peer?Schemas and protocol primitives are relatively explicitThe Remote Agent is normally treated as an opaque system
Unit of workOperations such as tools/call and resources/readA Message or a stateful Task
Typical durationOften one concrete read or action, with progress supportDesigned for immediate through long-running, asynchronous, multi-turn work
Discoverytools/list, resources/list, prompts/listAgent Card with Skills, interfaces, and security requirements
ResultContent, structured content, or resourcesMessage, status updates, and Artifacts
Common transportstdio and Streamable HTTPJSON-RPC, REST, or gRPC bindings over network transports; SSE can stream updates
Security focusTool permissions, input validation, local processes, prompt injectionAgent 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.

Different abstraction boundaries in MCP and A2A

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:

  1. inspect the order and payment records;
  2. apply refund policy;
  3. check fraud signals;
  4. request missing evidence;
  5. invoke a payment tool;
  6. 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.

The same refund modeled as an MCP tool and an A2A task

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 outputSchema and 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 objectPurposeRefund example
MessageOne turn between agents“Investigate duplicate charge” or “Upload payment evidence”
PartContent container inside a Message or ArtifactText, file reference, bytes, or structured data
TaskA stateful unit of work with an ID and lifecycleThe refund investigation
ArtifactA tangible result produced by a TaskDecision 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

A2A connects agents while MCP connects each agent to its tools

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:

  1. Am I invoking a defined operation or delegating a goal?
  2. Do I need an immediate result or a tracked task with states and artifacts?
  3. 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.

Official references

Related posts

Run your Agent workflow through Nbility

Get an API key and connect OpenAI-compatible models and developer tools from one place.

Manage API keys