Why these surfaces exist
The product contract should stay stable whether a caller imports the SDK directly or connects over a transport. ACP, A2A, AG-UI, and runtime MCP are transport or protocol views over the same persisted requests, sessions, approvals, events, artifacts, and recovery behavior.
Boundary rule
These surfaces do not create alternate execution semantics. They expose the runtime boundary that the harness already owns, while execution remains upstream in the chosen backend and future adapters.
Protocol responsibility matrix
Primary client-to-runtime protocol for IDEs, CLIs, and remote operator services.
Minimal agent-to-agent bridge for task submission, polling, cancellation, and agent-card discovery.
UI-facing SSE bridge for request lifecycle, text output, thinking, step progress, and tool-call rendering.
Control-plane inspection and operator actions exposed outward as MCP tools.
Keep the split explicit: MCP is the tool-and-context plane, ACP is the primary editor or client runtime boundary, A2A is the agent-platform bridge, and AG-UI is the UI event surface. None of these adapters should redefine execution semantics or create a second workflow engine.
Compatibility checkpoints
Shipped protocol promises should be backed by regression tests, not only adapter prose. The current
gate verifies that ACP request submission, A2A task lookup plus continuation, and runtime MCP
inspection all resolve to the same persisted sessionId and requestId records.
In practice, that means external protocol surfaces are allowed to rename fields such as
contextId or task.id, but they are not allowed to create shadow persistence
models or protocol-specific state machines outside the stable runtime contract.
ACP
createAcpServer(...)
serveAcpStdio(...)
serveAcpHttp(...)
ACP is the primary standard runtime-boundary direction. Use it when IDEs, CLIs, or remote clients need a session-centered protocol with request submission, event subscription, approval resolution, and artifact lookup projected from harness persistence.
Validated wire shape
The shipped ACP transports are now validated for the core reference-client flow: capability discovery, request submission, session lookup, request lookup, newline-delimited stdio JSON-RPC, HTTP JSON-RPC, SSE runtime notifications, invalid-JSON handling, and notification calls without response ids.
Best for embedded local clients, subprocess integrations, or direct IDE wiring.
Best for remote operator surfaces and services that need JSON-RPC plus runtime event streaming.
If you need the thinnest editor or CLI starter, begin with
agent-harness acp serve --workspace . --transport stdio and pair it with the
examples/03_protocol-surfaces/app/acp-stdio/main.mjs example. It uses the same
newline-delimited JSON-RPC wire shape that an IDE sidecar or subprocess client would send.
When a product needs an embedded client instead of only a server process, use
createAcpStdioClient(...). It is the small reference client for request/notification
demultiplexing over stdio, so IDE and CLI sidecars do not need bespoke JSON-line parsers.
A2A
serveA2aHttp(...)
Use the A2A bridge when another agent platform needs a small agent-to-agent HTTP JSON-RPC surface with task submission, listing, cancellation, agent card discovery, SSE task streaming, and webhook push notifications with polling compatibility over the same persisted runtime records.
The bridge keeps both legacy method names such as message/send and newer aliases such as
SendMessage, GetTask, ListTasks, CancelTask, and
SubscribeToTask so compatibility work can happen in the adapter layer instead of leaking into
product-facing runtime semantics.
The A2A bridge now aligns its public agent card and PascalCase JSON-RPC methods with the A2A v1.0 shape:
supportedInterfaces contains protocol binding entries, task states use the
TASK_STATE_* enum strings, SendMessage returns the { task } response
wrapper, and ListTasks accepts status, pageSize, and
pageToken. Legacy lowercase methods remain accepted for older integrations.
Discovery is now slightly friendlier for mixed clients as well: the agent-card path responds to
GET, HEAD, and OPTIONS, and JSON-RPC callers can fetch the same
card through GetAgentCard before asking for GetExtendedAgentCard.
For teams experimenting with registries or signed-card rollouts, the bridge can also expose optional registry URLs and detached card-signature metadata. Those fields are compatibility hints for surrounding discovery infrastructure, not a second harness-owned identity or trust system.
Streaming callers can use SendStreamingMessage or SubscribeToTask with
Accept: text/event-stream to receive SSE task snapshots, while older poll-based clients can
keep using task lookup and list flows without changing the runtime contract.
AG-UI
serveAgUiHttp(...)
Use AG-UI when a UI client wants SSE-based request lifecycle and text streaming without importing the runtime SDK. The bridge projects stable runtime events onto AG-UI-style run, text, thinking, step, and tool-call messages so a UI can render more than a plain transcript.
Runtime MCP
createRuntimeMcpServer(...)
serveRuntimeMcpOverStdio(...)
Runtime MCP exposes the runtime control plane itself as MCP tools. Use it when another agent or operator surface should inspect sessions, requests, approvals, events, artifacts, or export evidence packages through MCP instead of custom local SDK code.
This is also the place where runtime governance becomes visible to buyers and operators: remote MCP allowlists, trust tier, tenant scope, approval escalation, prompt-injection risk, and OAuth-scope policy stay runtime-owned instead of becoming ad hoc tool metadata.
The same control plane now also exposes whether a governed tool stays on manual approval or shifts into an automatic runtime decision mode such as auto-approve or auto-reject, so audit views do not need to infer policy from scattered tool definitions.
How to choose
When you need the clearest runtime-centered protocol surface for external clients.
When another agent runtime or platform wants a minimal agent-to-agent bridge with SSE streaming, webhook push notifications, and poll-compatible task flows.
When a frontend or operator UI only needs run and text streaming over HTTP SSE.
When inspection and operator actions should look like MCP tools to another agent.
Operational checks
- Keep approvals, recovery, and artifact lookup anchored to harness persistence instead of backend-native checkpoint objects.
- Do not let transport adapters invent second copies of runtime state or second execution semantics.
- Publish the compatibility matrix you actually validate, especially for ACP client discovery, session lookup, submit, stream, approval, and request replay flows.
- Document the chosen transport in product-facing docs so operators know which boundary is canonical.
- Test session lookup, request submission, approval flow, and evidence export through the selected transport before release.