April 28th, 2026
0 reactions

A2A v1 Is Here: Cross-Platform Agent Communication in Microsoft Agent Framework for .NET

Principal Software Engineer

As organizations move from single-agent prototypes to multi-agent production systems, the ability for agents to communicate reliably across platforms and organizational boundaries becomes essential. With the release of A2A Protocol v1.0 and updated support in the Microsoft Agent Framework, you can now connect and expose your AI agents using a stable, production-ready interoperability standard – whether you’re consuming remote agents or hosting your own.

Both the A2A Agent (client-side) and A2A Hosting (server-side) .NET packages in the Agent Framework have been updated to the A2A v1 SDK. This means you can discover and call remote A2A agents from any vendor, and expose your own agents so that any A2A-compliant client can reach them – all using a protocol backed by a technical steering committee with representatives from AWS, Cisco, Google, IBM Research, Microsoft, Salesforce, SAP, and ServiceNow.

Why Interoperability Matters

In practice, multi-agent systems rarely live inside a single team or a single vendor stack. A procurement agent might need to consult a partner’s compliance service. A customer-support agent might hand off to a specialized agent built by a different division on a completely different platform. When each boundary requires custom integration code, the cost of connecting agents grows faster than the value they deliver.

An open, standardized protocol for agent-to-agent communication removes that friction. It lets teams build agents with whatever framework fits their needs and connect them without bespoke glue code – the same way HTTP and REST made it possible to compose web services regardless of the language or platform behind them.

How the Agent Framework Enables It

A2A support in the Agent Framework is designed so that interop comes for free – you don’t have to restructure your code or learn a separate programming model to take advantage of it.

A remote A2A agent is just an AIAgent in your code. Same RunAsync, same streaming, same session handling. Swap a local Azure OpenAI agent for a remote A2A agent without touching the calling code, or compose them side by side in the same multi-agent workflow – sequential, concurrent, handoff, or group chat. A2A agents are first-class workflow participants alongside agents from any other provider.

The same applies in reverse. Any AIAgent you’ve already built – on Microsoft Foundry, Azure OpenAI, OpenAI, Anthropic, AWS Bedrock, or any other supported provider – can be exposed as an A2A endpoint with a few lines of hosting code. There’s no protocol boilerplate to write, and no rewrite required when you decide to make an internal agent available across teams or to external partners.

Why Now?

The A2A Protocol v1.0 is the first stable, production-ready version of the open standard for agent-to-agent communication. If you were using the earlier v0.3 draft, the v1 release tightens specification behavior and addresses enterprise requirements. Here are a few highlights:

  • Stability and long-term support – v1.0 signals that the core protocol is mature and ready for production investment. Rough edges from earlier drafts have been smoothed out, ambiguous areas clarified, and the API surface designed for durability.
  • Enterprise-grade features – multi-tenancy support, signed Agent Cards for cryptographic identity verification, and improved security flows make A2A v1 suitable for regulated and multi-party environments.
  • Web-aligned architecture – A2A v1 builds on industry-proven protocols and infrastructure patterns. You can scale agent interactions using the same load balancing, gateway, and observability tools you already use for web services.

Connect to a Remote A2A Agent

If you’ve used A2AAgent in the Agent Framework before, the API is essentially unchanged – we updated the underlying SDK to A2A v1 with almost no breaking changes, so existing code continues to work with only minor tweaks. The familiar discovery patterns and AIAgent abstraction remain the same. As a quick refresher, here’s how to connect to a remote A2A agent.

The A2AAgent wraps any A2A-compliant endpoint as a standard AIAgent, so you can interact with remote agents – regardless of what framework or language they were built with – using the same RunAsync and RunStreamingAsync methods you use with local agents.

Discover and Connect via Well-Known URI

The A2A protocol defines a standard discovery path at /.well-known/agent-card.json. Use A2ACardResolver to fetch the agent card and create an agent in one call:

using A2A;
using Microsoft.Agents.AI;

// Point the resolver at the remote agent's host.
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));

// Resolve the agent card and create an AIAgent in one step.
AIAgent agent = await resolver.GetAIAgentAsync();

// Use the agent like any other AIAgent.
Console.WriteLine(await agent.RunAsync("What's the weather in Seattle?"));

Direct Configuration

For development scenarios or tightly coupled systems where the endpoint is known, create an A2AClient directly:

using A2A;
using Microsoft.Agents.AI;

A2AClient a2aClient = new(new Uri("https://a2a-agent.example.com"));

AIAgent agent = a2aClient.AsAIAgent(name: "my-agent", description: "A helpful assistant.");

Console.WriteLine(await agent.RunAsync("What can you help me with?"));

Protocol Selection

A2A v1 agents can expose multiple protocol bindings. By default, Agent Framework prefers HTTP+JSON with JSON-RPC as a fallback. You can control this explicitly:

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));

A2AClientOptions options = new()
{
    PreferredBindings = [ProtocolBindingNames.HttpJson]
};

AIAgent agent = await resolver.GetAIAgentAsync(options: options);

Stream Responses

A2A supports streaming via Server-Sent Events. Use RunStreamingAsync to receive updates in real time:

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

await foreach (var update in agent.RunStreamingAsync("Write a short summary of quantum computing."))
{
    if (!string.IsNullOrEmpty(update.Text))
    {
        Console.Write(update.Text);
    }
}

Host Your Agent as an A2A Endpoint

The hosting packages let you expose any AIAgent via the A2A protocol so that any A2A-compliant client – built with any framework, in any language – can discover and communicate with your agent. The hosting API has been refined for A2A v1: server registration, endpoint mapping, and agent card discovery are now separate, explicit steps. The flow will feel familiar if you’ve hosted agents with the Agent Framework before – the migration guide covers what changed.

Here’s a minimal ASP.NET Core application that hosts a single agent over A2A:

using A2A;
using A2A.AspNetCore;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var builder = WebApplication.CreateBuilder(args);

// 1. Create and register the agent.
builder.Services.AddKeyedSingleton<AIAgent>("weather-agent", (sp, _) =>
{
    return new AIProjectClient(new Uri("https://your-project.azure.com"), new DefaultAzureCredential())
        .AsAIAgent(
            model: "gpt-4o-mini",
            instructions: "You are a helpful weather assistant.",
            name: "weather-agent");
});

// 2. Register the A2A server for the agent.
builder.AddA2AServer("weather-agent");

var app = builder.Build();

// 3. Map A2A protocol endpoints.
app.MapA2AHttpJson("weather-agent", "/a2a/weather-agent");

// 4. Serve an agent card for discovery.
app.MapWellKnownAgentCard(new AgentCard
{
    Name = "WeatherAgent",
    Description = "A helpful weather assistant.",
    SupportedInterfaces =
    [
        new AgentInterface
        {
            Url = "https://your-host/a2a/weather-agent",
            ProtocolBinding = ProtocolBindingNames.HttpJson,
            ProtocolVersion = "1.0",
        }
    ]
});

app.Run();

The agent is now reachable at https://your-host/a2a/weather-agent and its agent card is discoverable at https://your-host. You can also map MapA2AJsonRpc alongside MapA2AHttpJson to let clients choose their preferred transport.

Host Multiple Agents

A single application can host multiple agents, each with its own A2A server and endpoint:

// Register agents.
builder.Services.AddKeyedSingleton<AIAgent>("weather-agent", (sp, _) =>
    new AIProjectClient(new Uri("https://your-project.azure.com"), new DefaultAzureCredential())
        .AsAIAgent(model: "gpt-4o-mini", instructions: "You are a helpful weather assistant.", name: "weather-agent"));

builder.Services.AddKeyedSingleton<AIAgent>("scientist", (sp, _) =>
    new AIProjectClient(new Uri("https://your-project.azure.com"), new DefaultAzureCredential())
        .AsAIAgent(model: "gpt-4o-mini", instructions: "You are a scientist.", name: "scientist"));

// Register A2A servers.
builder.AddA2AServer("weather-agent");
builder.AddA2AServer("scientist");

var app = builder.Build();

// Map endpoints.
app.MapA2AHttpJson("weather-agent", "/a2a/weather-agent");
app.MapA2AHttpJson("scientist", "/a2a/scientist");

Putting It Together: Cross-Team Compliance Checks

To see how the pieces connect, consider a concrete scenario. Your team runs an internal procurement agent that handles purchase requests. Company policy requires every request above a certain threshold to pass a compliance review – but the compliance agent is maintained by a partner team with its own tech stack.

With the Agent Framework, neither team has to change how their agent is built. The partner team exposes their compliance agent as an A2A endpoint – the same AddA2AServer and MapA2AHttpJson pattern shown earlier. On your side, you add the partner’s agent to your workflow as a standard A2AAgent:

// Discover the partner team's compliance agent - it's just another AIAgent.
A2ACardResolver resolver = new(new Uri("https://compliance.partner-team.internal"));
AIAgent complianceAgent = await resolver.GetAIAgentAsync();

// Your existing procurement agent - unchanged.
AIAgent procurementAgent = projectClient
    .ProjectOpenAIClient
    .GetChatClient("gpt-4o-mini")
    .AsIChatClient()
    .AsAIAgent(
        instructions: "You handle purchase requests. Hand off to compliance when review is needed.",
        name: "procurement-agent");

// Compose them in a handoff workflow using AgentWorkflowBuilder.
Workflow workflow = AgentWorkflowBuilder
    .CreateHandoffBuilderWith(procurementAgent)
    .WithHandoffs(procurementAgent, complianceAgent)
    .Build();

The procurement agent’s code doesn’t know or care that the compliance agent runs on a different framework, in a different language, or behind a different cloud. It’s just another AIAgent. If the partner team later moves to a different platform, nothing changes on your side as long as they remain A2A-compliant. And when a third team wants to add a fraud-detection agent to the pipeline, it slots in the same way – no custom integration work, no protocol glue.

Migrating from A2A v0.3

If you have existing code that uses the Agent Framework’s A2A packages with the v0.3 SDK, this is a breaking change. The main differences:

Area v0.3 v1
Server registration Handled by MapA2A Separate AddA2AServer() step
Endpoint mapping app.MapA2A(agent, path, agentCard) app.MapA2AHttpJson("name", path) / app.MapA2AJsonRpc("name", path)
Agent card Inline parameter in MapA2A() Dedicated app.MapWellKnownAgentCard(card)
Protocol selection JSON-RPC only HTTP+JSON preferred, JSON-RPC fallback. Configurable via A2AClientOptions.PreferredBindings

The migration guide covers each change in detail with before-and-after examples.

Learn More

A2A v1 support is available in the .NET Agent Framework packages today.

Try itA2A Agent (client-side) · A2A Hosting (server-side)

🔁 Migrating?Migration guide from A2A v0.3 to v1

💬 EngageDiscussion boards – share feedback, ask questions, and connect with the community

Signal value – If you’ve been enjoying Agent Framework, give us a ⭐ on GitHub

📖 Deep diveA2A Protocol v1.0 announcement

Author

Sergey Menshykh
Principal Software Engineer

0 comments