We run SAP AI Lab — two of us, one in ML systems, one in enterprise information systems, independent of both vendors whose acronyms appear below. When SAP put A2A at the center of its BTP agentic stack at TechEd Berlin 2025 and Microsoft shipped an A2A endpoint in Foundry Agent Service, we tried to connect the two and wrote down every wall we hit. All facts below re-verified against SAP and Microsoft documentation as of 2026-11-08.
First, one line of context for anyone arriving late: the Agent2Agent protocol is the open standard for agents calling other agents — an Agent Card published at /.well-known/agent-card.json, then tasks with a real lifecycle (submitted → working → terminal states, with input-required for "a human must approve this"). It complements MCP rather than competing: MCP gives each agent depth against its tools, A2A gives the system reach across an organizational boundary. Google donated it to the Linux Foundation in 2025, where MCP also lives now, and both SAP and Microsoft ship first-party support.
The protocol mechanics were fine. The platform edges are where we lost an afternoon. Three constraints shaped the entire design.
1. Joule waits ~60 seconds. Plan your task topology around that.
The SAP side is clean on paper: a custom agent built in Joule Studio (GA since December 2025) with the namespace joule.ext, a capability file using agent-request against a BTP HTTP destination, deployed with the Joule Studio CLI. Two gotchas the docs make painful: the destination URL must point at the agent's base without the /.well-known/ suffix — Joule appends it itself — and the whole call is synchronous with a budget of roughly 60 seconds. A credit-block review that takes four minutes cannot live behind that timeout. Long work must become a task you surface through a status update or a follow-up turn that passes the same contextId and taskId back. Design for handoff, not for holding the connection.
2. The Foundry inbound endpoint will not stream to you.
Microsoft exposes an existing prompt agent as an A2A endpoint — genuinely no bespoke glue — but read the limits before sketching architecture: incoming A2A is text modality only, no SSE streaming, tasks and contexts retained 60 days after last write, and v1.0 bound to JSON-RPC only (no gRPC). Enablement isn't in the portal; it's a REST PATCH against the agent's endpoint/protocols/a2a path. Even if your SAP-side agent streams, cross this boundary with GetTask polling. We rebuilt a pretty streaming demo into a poll loop in about forty minutes.
3. Omit the version, and you silently get the old one.
This is the one we'd tattoo on a client laptop. One Foundry endpoint serves both A2A v1.0 (generally available) and v0.3 (preview). Today, omitting the version falls back to v0.3 — not the GA version. Pin it explicitly with the A2A-Version: 1.0 header or the versioned card path, and note that conflicting signals return HTTP 400 version-ambiguous. Pinning matters because v1.0 reshuffled the wire format: message/send became SendMessage, the kind discriminator and final flag are gone, enums are SCREAMING_SNAKE_CASE, and transport details moved into supportedInterfaces with a per-interface protocolVersion. Every v0.3-era snippet in your notes needs a moment of suspicion before you reuse it.
Two security notes while we're here. A public agent card advertises your skills to anyone probing the well-known URI — gate it, or serve an authenticated extended card. And on the Azure side, an A2A caller needs the Foundry Agent Consumer role at project or agent scope; key-based and anonymous card access aren't supported.
Our reference build uses a2a-sdk 1.3.0 (Python 3.12+) — the SDK handles wire format, task store, and streaming so your code is just an executor class. If the card format itself is what you're wrestling with, the Agent Card deep-dive covers URI, capabilities, and skills field by field, and the model layer behind your agents is its own integration project.
The full walkthrough with all the pricing sources and checklists is on our site: A2A Protocol with SAP Joule & Azure AI Foundry: A Practical Guide — step-by-step build, the working executor code, the destination setup, and the smoke tests we run before registering any endpoint.
Top comments (0)