Most agent tutorials assume your agent owns every tool it calls. Real systems aren't like that. Your booking agent needs to hand off to a payments agent your finance team runs; your research agent wants to delegate a legal question to an agent another company hosts. That's the job A2A — the Agent-to-Agent protocol — does, and as of Microsoft Agent Framework 1.0 (GA April 3, 2026) it's a first-class, built-in feature rather than something you bolt on. The agent-framework-a2a package handles both directions. Here's each, with code.

First, where A2A sits#

A2A is horizontal: agent-to-agent, across team and org boundaries. MCP, which the same framework also speaks, is vertical: agent-to-tool. They don't compete — you give an agent capabilities with MCP and let it delegate to peers with A2A. If you're still deciding which problem is which, our A2A vs MCP piece draws the line in full. For this how-to, the mental model is enough: A2A lets an agent call another agent it doesn't own.

Install the package (it's pre-release today):

pip install agent-framework-a2a --pre

Consuming a remote agent (the easy direction)#

If someone gives you an A2A endpoint, calling it is three lines. A2AAgent wraps the remote endpoint, resolves its capabilities from its AgentCard, and handles the protocol so you never touch JSON-RPC:

from agent_framework.a2a import A2AAgent

a2a_agent = A2AAgent(url="https://their-agent.example.com/a2a")
response = await a2a_agent.run("Summarize the Q2 filing and flag any risk language.")
print(response)

If you want to inspect a remote agent before committing to it — check its skills, its supported input/output modes — resolve its card explicitly first:

import httpx
from a2a.client import A2ACardResolver

async with httpx.AsyncClient(timeout=60.0) as http_client:
    resolver = A2ACardResolver(httpx_client=http_client, base_url="https://their-agent.example.com")
    card = await resolver.get_agent_card()   # from /.well-known/agent.json
    print(card.name, [s.id for s in card.skills])

The card lives at /.well-known/agent.json and describes the agent's name, description, skills, supported I/O modes, and endpoints — the whole contract, discoverable without an integration call.

Exposing your agent (so others can call you)#

The more interesting direction: publish one of your own agents so other people's agents can discover and use it. A2AExecutor adapts any Agent Framework agent to the A2A server side, and the official a2a-sdk gives you a Starlette/ASGI app to host it:

from agent_framework.a2a import A2AExecutor
from a2a.server.apps import A2AStarletteApplication
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.tasks import InMemoryTaskStore

# my_agent is any Agent Framework agent you've already built.
executor = A2AExecutor(agent=my_agent)

request_handler = DefaultRequestHandler(
    agent_executor=executor,
    task_store=InMemoryTaskStore(),   # swap for a durable store in production
)

app = A2AStarletteApplication(
    agent_card=my_agent_card,          # published at /.well-known/agent.json
    http_handler=request_handler,
).build()

# app is a standard ASGI app — serve it with uvicorn like any web service.

That's the whole server. The agent_card you pass in is what the outside world discovers; fill it with an honest description and a real list of skills, because that card is your agent's public API.

Your AgentCard is not documentation about your agent. It is the interface other agents program against. Write it like a contract, because it is one.

The one thing that will bite you#

InMemoryTaskStore is fine on your laptop and wrong in production — restart the process and in-flight work vanishes. Swap in a durable store before you ship. And the bigger one: A2A's identifiers are for routing, not authorization. The moment your agent is reachable from outside, put authentication, rate limiting, and authorization at your deployment's normal auth layer — the same front door you'd put on any public API. An agent endpoint that any caller can hit is a tool any caller can abuse, and the protocol won't stop them for you.

Wire the consume side first — it's three lines and immediately useful. Expose an agent only once you've decided which of your capabilities is genuinely worth another team building against, and once its auth is real. If you're weighing Microsoft Agent Framework against the alternatives before you commit, we ran it through three decision thresholds — and for everything else that shipped this quarter, the founder's shipping log has the rest.