cd /news/ai-agents/mcp-connects-agents-to-tools-a2a-con… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-148123] src=dev.to β†— pub= topic=ai-agents verified=true sentiment=Β· neutral

MCP Connects Agents to Tools. A2A Connects Agents to Agents - Here's How to Debug It.

A developer published a debugging field guide for the Agent2Agent (A2A) protocol, contrasting it with MCP: MCP connects agents to tools and resources, while A2A connects agents to other agents through long-lived, stateful tasks. The guide documents that A2A 1.0 and 0.3 are not wire-compatible β€” method names differ (e.g., SendMessage vs. message/send) and 1.0 adds JSON-RPC, HTTP+JSON (REST) and gRPC bindings β€” and walks through fetching an agent's public Agent Card at /.well-known/agent-card.json and tracking a task through states like working, input-required, completed and failed.

by read6 min views2 publishedOct 9, 2026

MCP got the headlines, and deservedly so: it gave agents a standard way to call

tools β€” search the docs, query the database, hit an API. But tools are only

half of a multi-agent system. The other half is agents talking to each other: a support agent handing off to a billing agent, a research agent

That's the job of the Agent2Agent (A2A) protocol. And the moment you try to

debug an A2A call, you discover it's nothing like pointing curl at a REST route:

This article is the debugging field guide I wish existed β€” and how to inspect an

A2A conversation the same way you inspect an HTTP request.

MCP A2A
Connects an agent to tools and resources an agent to another agent
Unit of work a tool call a message that starts a task
Typical shape request/response, short-lived long-lived, stateful, often streaming
Discovery tool list an Agent Card describing skills and auth

If MCP is "call this function," A2A is "delegate this to a capable counterpart

and track the job."

The first thing that looks like a server bug is often just a version mismatch.

A2A 1.0 and 0.3 are explicitly not wire-compatible β€” the JSON-RPC

method names differ:

Capability A2A 1.0 A2A 0.3
Send a message SendMessage message/send
Stream a message SendStreamingMessage message/stream
Get a task GetTask tasks/get
Cancel a task CancelTask tasks/cancel
Subscribe to updates SubscribeToTask tasks/resubscribe
Authenticated card GetExtendedAgentCard agent/getAuthenticatedExtendedCard

A 1.0 client sending message/send will be rejected by a 1.0 server, and vice

versa. Before you inspect payloads, confirm both sides agree on the version.

A2A 1.0 also defines three bindings β€” JSON-RPC, HTTP+JSON (REST) and

gRPC β€” while 0.3 here is JSON-RPC only. Switching bindings changes the

envelope: JSON-RPC wraps everything; REST and gRPC take the bare params

object with no jsonrpc/ id wrapper. If you paste a JSON-RPC body into a REST

binding, that's a malformed request, not an agent failure.

You don't guess an agent's endpoint or capabilities. You fetch its public Agent

Card, conventionally served at:

{endpoint}/.well-known/agent-card.json

The card tells you what the agent can do (its skills), where it lives, which

transport it supports, and what authentication it expects. In a debugging tool

this is a one-click "fetch the public card" step β€” inspect the card JSON first,

because half of "the agent ignored my request" bugs are really "I sent a method

this agent never advertised."

This is the conceptual shift from REST. You don't call an endpoint and get the

result synchronously. You send a message, and the agent creates a task

that moves through states like working, input-required, completed and

failed. You then GetTask, ListTasks, CancelTask, or subscribe to

updates.

A minimal A2A 1.0 SendMessage over JSON-RPC looks like this:

{
  "jsonrpc": "2.0",
  "id": "a2a-0001",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "a2a-msg-0001",
      "role": "ROLE_USER",
      "parts": [{ "text": "Where is order A-10293?" }]
    }
  }
}

The same message on 0.3 is a different shape β€” lowercase role, a typed

part, and an explicit message kind:

{
  "jsonrpc": "2.0",
  "id": "a2a-0001",
  "method": "message/send",
  "params": {
    "message": {
      "messageId": "a2a-msg-0001",
      "role": "user",
      "kind": "message",
      "parts": [{ "kind": "text", "text": "Where is order A-10293?" }]
    }
  }
}

Task follow-ups take the task id:

{
  "jsonrpc": "2.0",
  "id": "a2a-0002",
  "method": "GetTask",
  "params": { "id": "<task-id-from-the-send-response>" }
}

When you're debugging, send the message, capture the returned task id, and then

walk the lifecycle explicitly. Treating A2A like a single synchronous RPC is the

most common source of "it sometimes returns nothing."

For anything that takes time, the agent doesn't block on one response; it

streams task updates (over SSE in the JSON-RPC binding). The streaming methods

are SendStreamingMessage and SubscribeToTask on 1.0, and message/stream

and tasks/resubscribe on 0.3.

Debugging these means inspecting the event sequence, not just the final

frame: did the task go working β†’ artifact/progress events β†’ completed, or

did it stall in input-required waiting on something you never sent? A stream

that ends without a terminal state is a different bug from one that returns an

error event, and a REST client that only reads the first chunk will miss both.

Authenticated A2A uses signed requests verified against a JWKS (a JSON Web

Key Set). Here's the subtle failure: an Agent Card can advertise where to fetch

keys, but blindly fetching keys from a URL the remote card itself provides means

the remote party is handing you both the lock and the key. A spoofed or

compromised card can then point you at attacker-controlled keys.

The safe pattern:

This is the same principle as TLS pinning and webhook-signature verification:

the trust anchor has to arrive independently of the signed payload.

Once you know the version, binding, card and task lifecycle, an A2A call is

debuggable with the same discipline you already use for REST β€” you just need a

client that speaks the envelope. In Powerduck, A2A sits alongside HTTP as a

first-class debug protocol: create a new A2A operation, pick the version

(1.0 / 0.3) and binding (JSON-RPC / HTTP+JSON / gRPC), paste the Agent Card URL

and fetch the public card, choose the method, edit the request from a valid

template, send it, and inspect the returned task or the streamed events.

That workflow enforces the rules above in the right order β€” unknown method or a

JSON-RPC envelope pasted into a REST binding is rejected up front, so you fix

the request shape before you go chasing agent behavior.

Debugging an existing agent needs no server. If you want your business service

callable over A2A, you can download an A2A 1.0 adapter template, wire it to

your own HTTP handler, and run it yourself. It receives A2A requests and returns

your business results over JSON-RPC, REST or gRPC.

Two expectations to set correctly: the adapter is a thin protocol bridge β€” it

does not ship an AI model or a persistent task engine, and you bring the

business logic and auth. That's deliberate: A2A is the transport between

capable agents, not a replacement for what your agent actually does.

What makes this manageable long-term is describing the underlying service once

and reaching it through the right surface for the caller: humans read the docs,

agents call tools over MCP, and other agents delegate over A2A. The protocol

differs; the contract shouldn't.

If you're integrating agents today, do the boring debugging first: pin the

version, fetch the card, send one message, capture the task id, walk the

lifecycle, pin the JWKS out of band. Most "agent interoperability" problems

dissolve into one of those five steps.

You can create and send A2A 1.0/0.3 requests (JSON-RPC, REST and gRPC), fetch

Agent Cards, inspect task/stream responses, and verify signatures in the free

web app at powerduck.com/app.

Have you hit an A2A integration yet β€” version mismatch, streaming, or the

signature/JWKS trust step? Tell me which one burned the most time in the

comments; I'm collecting the sharp edges as the protocol settles.

── more in #ai-agents 4 stories Β· sorted by recency
── more on @agent2agent 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/mcp-connects-agents-…] indexed:0 read:6min 2026-10-09 Β· β€”