Skip to main content

MCP and A2A: what is implemented

The two transport protocols an agent uses with the world, as agent-runtimes implements them today, in both languages, as a client and as a server; and the gaps against their latest specifications. Inventory taken on 2026-10-12 from the code (PR-01); it moves with the change that moves a row.

Versions​

PackagePinProtocol version
Python mcpmcp>=2,<3 (2.1.1 installed)2026-07-28 (mcp.types.LATEST_PROTOCOL_VERSION)
Python fastmcp-slim[client]>=4.0.0b3,<5the transports of the MCP client
Python pydantic-ai-slim[mcp]>=2.35.0,<3MCPToolset, which DisplayMCPToolset extends
TypeScript @modelcontextprotocol/sdk^1.32.1 (1.32.1 installed)2025-11-25 (MCP_SPECIFICATION_VERSION in src/protocols/mcp)
Python fasta2a>=2.1.1,<2.2 (extra a2a)A2A 1.0, JSON-RPC binding
Python a2a-sdk>=0.3.0,<0.4.0used by tests only, to validate agent cards
TypeScript @a2a-js/sdk^1.3.0A2A 1.0 method names

The two MCP SDKs speak different protocol versions: Python 2026-07-28, TypeScript 2025-11-25. The Python server answers a TypeScript client at 2025-11-25 (the initialize handshake), held by test_protocols_mcp_two_languages.py.

MCP​

agent-runtimes is an MCP client, in Python, for tools. It serves no MCP server of its own in either language: /api/v1/mcp/proxy/… is a REST proxy and /api/v1/mcp-ui/… an agent chat transport.

FeaturePython clientTypeScript clientServer (either)
stdioyes (mcp/lifecycle.py)through McpClient.connect({ transport })no
Streamable HTTPyes (mcp/tools.py, mcp/datalayer_gateway.py, mcp/google_workspace.py)yes (McpClient in src/protocols/mcp/client.ts)no
Legacy HTTP+SSEnot usednono
Tools: list, callyes (mcp/lifecycle.py, mcp/displays.py)yes (McpClient.listTools, callTool; the page still manages a runtime's servers through its REST routes)no
A tool's display (_meta["reactor.ui/display"])yes (mcp/displays.py)drawn from the runtime's streamno
Structured content, output schemas, annotationsread (protocols/mcp/reading.py, the conformance's readings); through pydantic-ai for an agent's toolsread (toolReading, callReading; a structured answer checked against its output schema by the SDK)no
Resources, promptsread (resource_reading, prompt_reading); not wired to an agentread (readResource, getPrompt)no
Sampling, elicitation, rootsnonono
Logging, progress, cancellation, completionsnonono
Taskslibrary only (mcp/tasks.py: call as a task, get, cancel, list, status)nono
AuthorizationOAuth 2.1 flow (mcp/auth/: RFC 9728 and 8414 discovery, dynamic registration, PKCE, client ID metadata documents) behind routes/mcp_auth.py; the bearer sent comes from headers (the gateway's, a configured header)no—
MCP UI (ui://)—drawn from activity messages (MCPUIPlugin); text/html and remote DOM refused by designui:// resources built for the mcp-ui chat transport (transports/mcp_ui.py), not an MCP server

On Datalayer, an application reaches MCP servers through the MCP gateway, which holds the credentials and decides each call (the pap and pact toolsets are served there); the runtime holds the gateway's bearer only.

A2A​

agent-runtimes serves A2A in Python (fasta2a) and calls A2A agents from both languages.

FeaturePython clientPython serverTypeScript client
BindingJSON-RPC (fasta2a.client.A2AClient, subagents/a2a.py)JSON-RPC 2.0, POST at /api/v1/a2a/agents/{id}/ (routes/a2a.py)JSON-RPC (@a2a-js/sdk in runtimes/browser/a2aPeer.ts; A2AAdapter.ts, useA2A.tsx by hand)
HTTP+JSON, gRPCnonono
Agent card at /.well-known/agent-card.jsonyesyesyes
SendMessage / message/send—yesyes (useA2A.tsx)
SendStreamingMessage / message/streamyesyes (SSE)yes (A2AAdapter.ts, a2aPeer.ts)
GetTaskyes (polling)yesyes
CancelTaskyesyesno: A2AAdapter cancels through the runtime's /api/v1/a2a/terminate
SubscribeToTasknoyesno
ListTasksnoanswers unsupportedno
Push notification configsnoanswers not supported; the card says pushNotifications: falseno
Authenticated extended cardnonono
Securitybearerthe card's Bearer scheme; an application's route gated (apps/a2a.py); signed requests verified (Web Bot Auth)bearer
Extensionsthe orchestration extension's routesA2A-Extensions negotiated, required extensions checked; card extensions from the A2A plugin's points and the Appspec (Agent protocols)A2A-Extensions header

A harness over A2A (SH-15)​

An application whose agent is a harness (Claude Code, Codex, any ACP agent) is served by the same worker, plus: its plan as one artifact replaced as it progresses; each file it changed as a text/x-diff artifact named by its path, with the orchestration extension's artifactProvenance (sha256: of the body, when, from what); its tool calls as working statuses carrying {kind, title, status}; a permission as input-required carrying approvalRequest {toolCall, options, expiresAt}, answered on the same task by a message naming it — datalayer.approval {optionId}, or one whole word (yes, no, always, an option's name) from a caller without the extension; reasoning never an artifact. The card's skills come from the harness spec, text/x-diff among its output modes. The extension's schema describes these three fields since 15 October 2026.

Gaps​

  1. No MCP server in agent-runtimes; an application is reached over A2A, AG-UI or Vercel AI, never as an MCP server.
  2. MCP beyond tools: resources, prompts, sampling, elicitation, roots, logging, progress, completions and cancellation are not wired, although pydantic-ai supports several. Each becomes mcp.extension.<name> when it is.
  3. MCP OAuth stores a token after the flow but does not attach a stored token when connecting: on Datalayer the gateway holds credentials instead.
  4. MCP tasks are library code that only tests call.
  5. The TypeScript MCP client (McpClient, on @modelcontextprotocol/sdk) is a library: no page of the package uses it yet.
  6. Two MCP versions across the SDKs (2026-07-28, 2025-11-25).
  7. A2A server: JSON-RPC only (no HTTP+JSON binding, which PACT 1.0 requires of a Brand); push notifications and ListTasks answer unsupported; no authenticated extended card.
  8. TypeScript A2A: cancels through a runtime route rather than CancelTask; no client resubscribes.