/ docs · functional specification

The full platform
functional reference.

Every functional area of AI API Mapper documented at implementation depth so architects, security reviewers, and platform engineers can evaluate the product with real technical context.

A2A · Overview

A2A

Purpose

A2A (Agent2Agent) is the platform's second AI-facing protocol surface, alongside MCP. Where MCP governs discrete tool calls, A2A governs agent-to-agent conversations. The platform exposes the same published capabilities — Mapping toolsets and any other capability contributor — through both surfaces, under the same tenant/client scoping, governance authorization, credential brokering, and audit pipeline.

Functionally, A2A is the component that lets another agent (an orchestrator, a third-party AI system) discover and invoke ApiMapper's governed tools as A2A skills, without ApiMapper forking any of its existing tool catalog, authorization, or invocation logic to do it.

What A2A Does

A2A supports two roles. Every registered agent is one of two kinds, deciding what actually executes when a caller reaches it:

  • A2A Server (Phase 1): the platform's own published capabilities are exposed as an Agent Card with skills, callable by any A2A-compliant client. Task status transitions can additionally be pushed to a caller-registered webhook — see A2A Push Notifications.
  • A2A Concentrator (Phase 3): a governed proxy/hub for agent-to-agent traffic between other systems — a directory of registered remote agents (RegisteredAgent of kind RemoteAgent) that ApiMapper calls out to on a caller's behalf, with the same credential custody and audit trail the platform already gives downstream HTTP/SOAP APIs. A registered agent's own Agent Card is ingested (fetched and cached, display-only) and served back to callers two ways: composed into a client's own composite Agent Card alongside local skills, or, when explicitly opted in, reachable directly at its own per-agent route. Portal.Api/Portal.Web CRUD for registering agents, granting access policies, and authoring these composite-inclusion/direct-passthrough opt-ins is available in the Agent Directory admin page.
  • A2A Hosted Agent (Phase 5, LLM-backed): the other kind of registered agent (RegisteredAgent of kind HostedAgent) executes locally, reasoning with an LLM instead of proxying to a remote peer. An admin defines one or more Skills on a hosted agent — a name, a prompt, and an explicit, curated subset of individual tools drawn from the tenant's MCP toolsets and ESRA exposures marked available to Hosted Agents — and a caller's message is handed to that skill's LLM turn, built on Microsoft Agent Framework. The LLM decides which tool to call and with what arguments (every call still goes through the exact same governed tool invocation pipeline a deterministic call uses), or, if the request is incomplete, asks a clarifying question instead of failing outright. See A2A Hosted Agent Mode.

Main Flow (Phase 1 — server direction, deterministic Mapping-tool skills)

The flow below describes the deterministic, non-LLM server direction — the platform's tenant-wide skill catalog, unchanged since Phase 1. A Hosted Agent's skill turn follows a different flow (an LLM reasons over a curated tool subset instead of a direct one-to-one skill/tool resolution); see A2A Hosted Agent Mode for that flow.

  1. A caller identifies a tenant and client application, same as MCP.
  2. The caller requests the Agent Card (GET /.well-known/agent-card.json, or the authenticated extended card via JSON-RPC GetExtendedAgentCard).
  3. The Agent Card's skills[] is the same authorization-filtered tool catalog tools/list returns, MCP or A2A protocol notwithstanding — reshaped, not recomputed.
  4. The caller sends a SendMessage naming a skill. The platform resolves it back to the exact same governance authorization → credential resolution → downstream invocation → audit pipeline tools/call uses.
  5. Because a Mapping-backed skill invocation is fundamentally one governed HTTP/SOAP call, every SendMessage/SendStreamingMessage executes synchronously to completion and produces a Task object already in a terminal state (completed or failed). SendStreamingMessage reports this over a stream (submitted then the terminal state) instead of a single JSON response, but the underlying execution is identical — there is no long-running local execution to report on. The resulting task is persisted, so it can be retrieved afterward via GetTask or reconnected to via SubscribeToTask. See A2A Task Lifecycle.

Functional Capabilities

This is the full capability set for A2A protocol support — server mode (both deterministic Mapping-tool skills and LLM-backed Hosted Agent skills), streaming/task store, concentrator mode, push notifications/monitoring, and the gRPC/REST transport bindings below are all implemented. Further work (Agent Card signing, SDK client support, auto-bridging between MCP and A2A catalogs) is filed as a follow-up plan, not scheduled.

Protocol Version and Wire Shape

A2A 1.0.0, served over three transports, all mounted under the same /runtime/{tenantId}/{clientId}/a2a prefix and dispatching into the identical handler classes — no business logic is duplicated per transport:

  • JSON-RPC 2.0 (POST /runtime/{tenantId}/{clientId}/a2a) — the original transport; also carries the two inherently-streaming methods (SendStreamingMessage, SubscribeToTask) as an SSE upgrade.
  • gRPC (A2aGrpcServiceImpl, src/Runtime/CodedProjects.AI.ApiMapper.Runtime.A2a/Grpc/) — a proto service (a2a.proto) exposing the same method set as unary/server-streaming RPCs (SendMessage, SendStreamingMessage, GetTask, CancelTask, SubscribeToTask, the four push-notification-config RPCs, GetExtendedAgentCard). Registered via services.AddGrpc() and mapped with MapGrpcService<A2aGrpcServiceImpl>() under the same tenant/client route group. Because gRPC needs HTTP/2 without TLS (h2c) and a single Kestrel endpoint can't multiplex HTTP/1.1 and HTTP/2 without ALPN, Runtime.Host and Gateway.Host each expose a second, dedicated HTTP/2-only endpoint for it.
  • REST/JSON (A2aRestTransportEndpointRouteBuilderExtensions) — the spec's REST path table (POST /message:send, POST /message:stream as SSE, GET /tasks/{id}, POST /tasks/{id}:cancel, POST /tasks/{id}:subscribe as SSE, the push-notification-config CRUD routes, GET /extendedAgentCard) via plain System.Text.Json body binding — no protobuf involved.

Every transport reuses A2aHttpGuard and the same rate-limit policies, so there is no separate security posture per transport. Method names are PascalCase (SendMessage, GetTask, GetExtendedAgentCard), matching the unified naming the A2A 1.0 specification uses across its JSON-RPC, gRPC, and REST bindings — not the slash-style names (message/send) found in pre-1.0 drafts of the specification.

Governance and Audit

A2A reuses every control MCP already has, applied to the new surface: RuntimeRequestContextMiddleware for inbound authentication, IRuntimeGovernanceAuthorizer for authorization (unchanged — an A2A skill invocation is a tool invocation), and IGovernanceAuditWriter for the audit trail. A2A audit records are written under the same Category = "runtime" MCP already uses, so a mixed MCP/A2A execution trace renders as one coherent call in the Call Flow Dashboard with no additional wiring. The Call Flow Dashboard and its underlying call-list recognize every A2A action with its own icon, label, and call-type badge — the same way it already recognizes MCP's own tools/call/tools/list-style actions — rather than showing A2A traffic with a generic fallback.

Supported Integrations

The server direction uses the same integrations Runtime already has for MCP — same trusted identity providers, same Azure Key Vault-backed secret resolution, same downstream HTTP/SOAP target systems. Concentrator mode (Phase 3) adds registered remote agents as a new kind of governed outbound integration, reusing DownstreamSecurity's existing TargetSystem/TargetAuthenticationProfile credential-broker infrastructure rather than introducing a parallel connection/credential model for agents. Push notifications (Phase 4) add one further outbound integration point — a caller-registered webhook per task — governed by the same outbound allowlist and credential-custody rules as every other outbound call this platform makes, never a special case. See A2A Push Notifications.