{"id":5367,"date":"2026-04-28T13:57:51","date_gmt":"2026-04-28T20:57:51","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/agent-framework\/?p=5367"},"modified":"2026-05-01T09:31:09","modified_gmt":"2026-05-01T16:31:09","slug":"a2a-v1-is-here-cross-platform-agent-communication-in-microsoft-agent-framework-for-net","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/a2a-v1-is-here-cross-platform-agent-communication-in-microsoft-agent-framework-for-net\/","title":{"rendered":"A2A v1 Is Here: Cross-Platform Agent Communication in Microsoft Agent Framework for .NET"},"content":{"rendered":"<p>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 &#8211; whether you&#8217;re consuming remote agents or hosting your own.<\/p>\n<p>Both the <strong>A2A Agent<\/strong> (client-side) and <strong>A2A Hosting<\/strong> (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 &#8211; all using a protocol backed by a technical steering committee with representatives from AWS, Cisco, Google, IBM Research, Microsoft, Salesforce, SAP, and ServiceNow.<\/p>\n<p><div class=\"alert alert-primary\">While the A2A protocol itself has reached v1 (stable), the A2A SDK and the Agent Framework packages that implement it are still in preview.<\/div><\/p>\n<h2>Why Interoperability Matters<\/h2>\n<p>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&#8217;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.<\/p>\n<p>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 &#8211; the same way HTTP and REST made it possible to compose web services regardless of the language or platform behind them.<\/p>\n<h2>How the Agent Framework Enables It<\/h2>\n<p>A2A support in the Agent Framework is designed so that interop comes for free &#8211; you don&#8217;t have to restructure your code or learn a separate programming model to take advantage of it.<\/p>\n<p>A remote A2A agent is just an <code>AIAgent<\/code> in your code. Same <code>RunAsync<\/code>, 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 &#8211; sequential, concurrent, handoff, or group chat. A2A agents are first-class workflow participants alongside agents from any other provider.<\/p>\n<p>The same applies in reverse. Any <code>AIAgent<\/code> you&#8217;ve already built &#8211; on Microsoft Foundry, Azure OpenAI, OpenAI, Anthropic, AWS Bedrock, or any other supported provider &#8211; can be exposed as an A2A endpoint with a few lines of hosting code. There&#8217;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.<\/p>\n<h2>Why Now?<\/h2>\n<p>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:<\/p>\n<ul>\n<li><strong>Stability and long-term support<\/strong> &#8211; 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.<\/li>\n<li><strong>Enterprise-grade features<\/strong> &#8211; multi-tenancy support, signed Agent Cards for cryptographic identity verification, and improved security flows make A2A v1 suitable for regulated and multi-party environments.<\/li>\n<li><strong>Web-aligned architecture<\/strong> &#8211; 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.<\/li>\n<\/ul>\n<h2>Connect to a Remote A2A Agent<\/h2>\n<p>If you&#8217;ve used <code>A2AAgent<\/code> in the Agent Framework before, the API is essentially unchanged &#8211; 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 <code>AIAgent<\/code> abstraction remain the same. As a quick refresher, here&#8217;s how to connect to a remote A2A agent.<\/p>\n<p>The <code>A2AAgent<\/code> wraps any A2A-compliant endpoint as a standard <code>AIAgent<\/code>, so you can interact with remote agents &#8211; regardless of what framework or language they were built with &#8211; using the same <code>RunAsync<\/code> and <code>RunStreamingAsync<\/code> methods you use with local agents.<\/p>\n<h3>Discover and Connect via Well-Known URI<\/h3>\n<p>The A2A protocol defines a standard discovery path at <code>\/.well-known\/agent-card.json<\/code>. Use <code>A2ACardResolver<\/code> to fetch the agent card and create an agent in one call:<\/p>\n<pre><code class=\"language-csharp\">using A2A;\r\nusing Microsoft.Agents.AI;\r\n\r\n\/\/ Point the resolver at the remote agent's host.\r\nA2ACardResolver resolver = new(new Uri(\"https:\/\/a2a-agent.example.com\"));\r\n\r\n\/\/ Resolve the agent card and create an AIAgent in one step.\r\nAIAgent agent = await resolver.GetAIAgentAsync();\r\n\r\n\/\/ Use the agent like any other AIAgent.\r\nConsole.WriteLine(await agent.RunAsync(\"What's the weather in Seattle?\"));<\/code><\/pre>\n<h3>Direct Configuration<\/h3>\n<p>For development scenarios or tightly coupled systems where the endpoint is known, create an <code>A2AClient<\/code> directly:<\/p>\n<pre><code class=\"language-csharp\">using A2A;\r\nusing Microsoft.Agents.AI;\r\n\r\nA2AClient a2aClient = new(new Uri(\"https:\/\/a2a-agent.example.com\"));\r\n\r\nAIAgent agent = a2aClient.AsAIAgent(name: \"my-agent\", description: \"A helpful assistant.\");\r\n\r\nConsole.WriteLine(await agent.RunAsync(\"What can you help me with?\"));<\/code><\/pre>\n<h3>Protocol Selection<\/h3>\n<p>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:<\/p>\n<pre><code class=\"language-csharp\">using A2A;\r\nusing Microsoft.Agents.AI;\r\n\r\nA2ACardResolver resolver = new(new Uri(\"https:\/\/a2a-agent.example.com\"));\r\n\r\nA2AClientOptions options = new()\r\n{\r\n    PreferredBindings = [ProtocolBindingNames.HttpJson]\r\n};\r\n\r\nAIAgent agent = await resolver.GetAIAgentAsync(options: options);<\/code><\/pre>\n<h3>Stream Responses<\/h3>\n<p>A2A supports streaming via Server-Sent Events. Use <code>RunStreamingAsync<\/code> to receive updates in real time:<\/p>\n<pre><code class=\"language-csharp\">using A2A;\r\nusing Microsoft.Agents.AI;\r\n\r\nA2ACardResolver resolver = new(new Uri(\"https:\/\/a2a-agent.example.com\"));\r\nAIAgent agent = await resolver.GetAIAgentAsync();\r\n\r\nawait foreach (var update in agent.RunStreamingAsync(\"Write a short summary of quantum computing.\"))\r\n{\r\n    if (!string.IsNullOrEmpty(update.Text))\r\n    {\r\n        Console.Write(update.Text);\r\n    }\r\n}<\/code><\/pre>\n<h2>Host Your Agent as an A2A Endpoint<\/h2>\n<p>The hosting packages let you expose any <code>AIAgent<\/code> via the A2A protocol so that any A2A-compliant client &#8211; built with any framework, in any language &#8211; 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&#8217;ve hosted agents with the Agent Framework before &#8211; the <a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/migration-guide\/agent-to-agent-sdk-v1\">migration guide<\/a> covers what changed.<\/p>\n<p>Here&#8217;s a minimal ASP.NET Core application that hosts a single agent over A2A:<\/p>\n<pre><code class=\"language-csharp\">using A2A;\r\nusing A2A.AspNetCore;\r\nusing Azure.AI.Projects;\r\nusing Azure.Identity;\r\nusing Microsoft.Agents.AI;\r\n\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\n\/\/ 1. Create and register the agent.\r\nbuilder.Services.AddKeyedSingleton&lt;AIAgent&gt;(\"weather-agent\", (sp, _) =&gt;\r\n{\r\n    return new AIProjectClient(new Uri(\"https:\/\/your-project.azure.com\"), new DefaultAzureCredential())\r\n        .AsAIAgent(\r\n            model: \"gpt-4o-mini\",\r\n            instructions: \"You are a helpful weather assistant.\",\r\n            name: \"weather-agent\");\r\n});\r\n\r\n\/\/ 2. Register the A2A server for the agent.\r\nbuilder.AddA2AServer(\"weather-agent\");\r\n\r\nvar app = builder.Build();\r\n\r\n\/\/ 3. Map A2A protocol endpoints.\r\napp.MapA2AHttpJson(\"weather-agent\", \"\/a2a\/weather-agent\");\r\n\r\n\/\/ 4. Serve an agent card for discovery.\r\napp.MapWellKnownAgentCard(new AgentCard\r\n{\r\n    Name = \"WeatherAgent\",\r\n    Description = \"A helpful weather assistant.\",\r\n    SupportedInterfaces =\r\n    [\r\n        new AgentInterface\r\n        {\r\n            Url = \"https:\/\/your-host\/a2a\/weather-agent\",\r\n            ProtocolBinding = ProtocolBindingNames.HttpJson,\r\n            ProtocolVersion = \"1.0\",\r\n        }\r\n    ]\r\n});\r\n\r\napp.Run();<\/code><\/pre>\n<p>The agent is now reachable at <code>https:\/\/your-host\/a2a\/weather-agent<\/code> and its agent card is discoverable at <code>https:\/\/your-host<\/code>. You can also map <code>MapA2AJsonRpc<\/code> alongside <code>MapA2AHttpJson<\/code> to let clients choose their preferred transport.<\/p>\n<h3>Host Multiple Agents<\/h3>\n<p>A single application can host multiple agents, each with its own A2A server and endpoint:<\/p>\n<pre><code class=\"language-csharp\">\/\/ Register agents.\r\nbuilder.Services.AddKeyedSingleton&lt;AIAgent&gt;(\"weather-agent\", (sp, _) =&gt;\r\n    new AIProjectClient(new Uri(\"https:\/\/your-project.azure.com\"), new DefaultAzureCredential())\r\n        .AsAIAgent(model: \"gpt-4o-mini\", instructions: \"You are a helpful weather assistant.\", name: \"weather-agent\"));\r\n\r\nbuilder.Services.AddKeyedSingleton&lt;AIAgent&gt;(\"scientist\", (sp, _) =&gt;\r\n    new AIProjectClient(new Uri(\"https:\/\/your-project.azure.com\"), new DefaultAzureCredential())\r\n        .AsAIAgent(model: \"gpt-4o-mini\", instructions: \"You are a scientist.\", name: \"scientist\"));\r\n\r\n\/\/ Register A2A servers.\r\nbuilder.AddA2AServer(\"weather-agent\");\r\nbuilder.AddA2AServer(\"scientist\");\r\n\r\nvar app = builder.Build();\r\n\r\n\/\/ Map endpoints.\r\napp.MapA2AHttpJson(\"weather-agent\", \"\/a2a\/weather-agent\");\r\napp.MapA2AHttpJson(\"scientist\", \"\/a2a\/scientist\");<\/code><\/pre>\n<h2>Putting It Together: Cross-Team Compliance Checks<\/h2>\n<p>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 &#8211; but the compliance agent is maintained by a partner team with its own tech stack.<\/p>\n<p>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 &#8211; the same <code>AddA2AServer<\/code> and <code>MapA2AHttpJson<\/code> pattern shown earlier. On your side, you add the partner&#8217;s agent to your workflow as a standard <code>A2AAgent<\/code>:<\/p>\n<pre><code class=\"language-csharp\">\/\/ Discover the partner team's compliance agent - it's just another AIAgent.\r\nA2ACardResolver resolver = new(new Uri(\"https:\/\/compliance.partner-team.internal\"));\r\nAIAgent complianceAgent = await resolver.GetAIAgentAsync();\r\n\r\n\/\/ Your existing procurement agent - unchanged.\r\nAIAgent procurementAgent = projectClient\r\n    .ProjectOpenAIClient\r\n    .GetChatClient(\"gpt-4o-mini\")\r\n    .AsIChatClient()\r\n    .AsAIAgent(\r\n        instructions: \"You handle purchase requests. Hand off to compliance when review is needed.\",\r\n        name: \"procurement-agent\");\r\n\r\n\/\/ Compose them in a handoff workflow using AgentWorkflowBuilder.\r\nWorkflow workflow = AgentWorkflowBuilder\r\n    .CreateHandoffBuilderWith(procurementAgent)\r\n    .WithHandoffs(procurementAgent, complianceAgent)\r\n    .Build();<\/code><\/pre>\n<p>The procurement agent&#8217;s code doesn&#8217;t know or care that the compliance agent runs on a different framework, in a different language, or behind a different cloud. It&#8217;s just another <code>AIAgent<\/code>. 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 &#8211; no custom integration work, no protocol glue.<\/p>\n<h2>Migrating from A2A v0.3<\/h2>\n<p>If you have existing code that uses the Agent Framework&#8217;s A2A packages with the v0.3 SDK, this is a breaking change. The main differences:<\/p>\n<table>\n<thead>\n<tr>\n<th>Area<\/th>\n<th>v0.3<\/th>\n<th>v1<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Server registration<\/td>\n<td>Handled by <code>MapA2A<\/code><\/td>\n<td>Separate <code>AddA2AServer()<\/code> step<\/td>\n<\/tr>\n<tr>\n<td>Endpoint mapping<\/td>\n<td><code>app.MapA2A(agent, path, agentCard)<\/code><\/td>\n<td><code>app.MapA2AHttpJson(\"name\", path)<\/code> \/ <code>app.MapA2AJsonRpc(\"name\", path)<\/code><\/td>\n<\/tr>\n<tr>\n<td>Agent card<\/td>\n<td>Inline parameter in <code>MapA2A()<\/code><\/td>\n<td>Dedicated <code>app.MapWellKnownAgentCard(card)<\/code><\/td>\n<\/tr>\n<tr>\n<td>Protocol selection<\/td>\n<td>JSON-RPC only<\/td>\n<td>HTTP+JSON preferred, JSON-RPC fallback. Configurable via <code>A2AClientOptions.PreferredBindings<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The <a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/migration-guide\/agent-to-agent-sdk-v1\">migration guide<\/a> covers each change in detail with before-and-after examples.<\/p>\n<h2>Learn More<\/h2>\n<p>A2A v1 support is available in the .NET Agent Framework packages today.<\/p>\n<p>\u2705 <strong>Try it<\/strong> &#8211; <a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/agents\/providers\/agent-to-agent?pivots=programming-language-csharp\">A2A Agent (client-side)<\/a> \u00b7 <a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/hosting\/agent-to-agent\">A2A Hosting (server-side)<\/a><\/p>\n<p>\ud83d\udd01 <strong>Migrating?<\/strong> &#8211; <a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/migration-guide\/agent-to-agent-sdk-v1\">Migration guide from A2A v0.3 to v1<\/a><\/p>\n<p>\ud83d\udcac <strong>Engage<\/strong> &#8211; <a href=\"https:\/\/github.com\/microsoft\/agent-framework\/discussions\">Discussion boards<\/a> &#8211; share feedback, ask questions, and connect with the community<\/p>\n<p>\u2b50 <strong>Signal value<\/strong> &#8211; If you&#8217;ve been enjoying Agent Framework, give us a <a href=\"https:\/\/github.com\/microsoft\/agent-framework\">\u2b50 on GitHub<\/a><\/p>\n<p>\ud83d\udcd6 <strong>Deep dive<\/strong> &#8211; <a href=\"https:\/\/a2a-protocol.org\/latest\/announcing-1.0\/#why-this-release-matters-now\">A2A Protocol v1.0 announcement<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &#8211; [&hellip;]<\/p>\n","protected":false},"author":157200,"featured_media":5386,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[78,142,143,47],"tags":[],"class_list":["post-5367","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-a2a","category-agent-framework","category-announcement"],"acf":[],"blog_post_summary":"<p>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 &#8211; [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/157200"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=5367"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5367\/revisions"}],"predecessor-version":[{"id":5403,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5367\/revisions\/5403"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/5386"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=5367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=5367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=5367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}