AG-UI (Agent-User Interaction Protocol)
An open, event-based protocol that standardizes real-time communication between AI agent backends and user-facing frontends. AG-UI fills the third side of the agentic protocol triangle: MCP handles agent-tool, A2A handles agent-agent, AG-UI handles agent-user.
An open, event-based protocol that standardizes real-time communication between AI agent backends and user-facing frontends. Born from CopilotKit’s work with LangGraph and CrewAI, AG-UI fills the third side of the agentic protocol triangle: MCP handles agent-tool, A2A handles agent-agent, AG-UI handles agent-user.
What is AG-UI?
AG-UI is a lightweight protocol that defines how AI agents stream structured events to frontend applications over HTTP SSE or WebSocket connections. Instead of each agent framework inventing its own way to push updates to a UI, AG-UI specifies ~17 standardized event types that cover the full lifecycle of an agent run: text streaming, tool calls, state synchronization, interrupts for human-in-the-loop, and custom events.
The protocol was created by CopilotKit and open-sourced as a standalone specification independent of any single framework. It is transport-agnostic – events are JSON objects that flow over SSE, WebSocket, or any bidirectional channel.
The Problem AG-UI Solves
Building production agent UIs is harder than it looks. Without a standard protocol, every agent-frontend integration is custom:
- LangGraph agents stream events in one format, CrewAI in another, AutoGen in yet another
- Frontends are tightly coupled to a specific agent backend – switching frameworks means rewriting the UI layer
- There is no standard way to handle human-in-the-loop interrupts, progressive state updates, or tool call visualization
- Every team builds bespoke SSE/WebSocket parsers for their agent output
- State synchronization between agent and frontend requires ad-hoc solutions
AG-UI solves this by defining a single event schema that any agent backend can emit and any frontend can consume. The agent backend becomes a pluggable component – swap LangGraph for CrewAI or a custom agent, and the frontend works unchanged.
Where AG-UI Fits in the Protocol Stack
| Protocol | Relationship | Analogy |
|---|---|---|
| MCP | Agent to Tool/Data | USB cable to peripherals |
| A2A | Agent to Agent | HTTP between web services |
| AG-UI | Agent to User Interface | WebSocket between server and browser |
In a typical enterprise flow: a user interacts with a frontend (AG-UI), which connects to an orchestrator agent. That orchestrator uses A2A to delegate tasks to specialist agents. Each specialist uses MCP to access tools and data sources. AG-UI is the last mile – the protocol that makes agents visible and interactive to humans.
Architecture
Communication Model
AG-UI uses a unidirectional event stream from agent to frontend, with the frontend able to send messages back through standard HTTP requests (making it effectively bidirectional). The core flow:
- Frontend sends a
RunAgentInputrequest (HTTP POST) containing messages, thread ID, and optional state - Agent backend processes the request and begins streaming events back via SSE or WebSocket
- Frontend receives typed JSON events and updates the UI progressively
- User can interact during execution – send messages, approve tool calls, or interrupt the agent
1
2
3
4
5
6
7
+-----------------+ HTTP POST (RunAgentInput) +------------------+
| | -----------------------------------------> | |
| Frontend | | Agent Backend |
| (React, etc.) | SSE/WebSocket Event Stream | (Any framework)|
| | <----------------------------------------- | |
+-----------------+ RUN_STARTED, TEXT_MESSAGE_CONTENT, +------------------+
TOOL_CALL_START, STATE_DELTA, ...
Transport Layer
AG-UI supports two transport mechanisms:
- HTTP SSE (Server-Sent Events): The default and simplest option. Agent opens an SSE connection and pushes events. Good for most use cases where the frontend primarily receives updates.
- WebSocket: For fully bidirectional real-time communication. Required when agents need to receive frequent mid-run input from the user or when sub-second latency matters.
Both transports carry the same JSON event payloads – the protocol is transport-agnostic.
How It Works: The 17 Event Types
AG-UI organizes events into five categories. Every event carries a type field, a timestamp, and category-specific data.
1. Lifecycle Events
These track the progress of an agent run from start to finish.
| Event | Purpose |
|---|---|
RUN_STARTED |
Agent execution has begun. Contains run ID and metadata. |
STEP_STARTED |
An individual step within the run has started. Enables progress tracking for multi-step agents. |
STEP_FINISHED |
A step has completed. Carries step output/result. |
RUN_FINISHED |
The entire run completed successfully. |
RUN_ERROR |
The run failed. Contains error details, stack traces, retry information. |
A minimal agent run emits: RUN_STARTED -> (work) -> RUN_FINISHED. Multi-step agents nest STEP_STARTED/STEP_FINISHED pairs inside the run lifecycle.
2. Text Message Events
These handle streaming text generation token-by-token, analogous to how ChatGPT streams responses.
| Event | Purpose |
|---|---|
TEXT_MESSAGE_START |
A new message begins. Contains messageId and role (assistant, system, developer, user, tool). |
TEXT_MESSAGE_CONTENT |
A chunk of text (delta). Emitted repeatedly as tokens are generated. |
TEXT_MESSAGE_END |
The message is complete. |
3. Tool Call Events
These expose agent tool usage to the frontend, enabling UIs that show what the agent is doing and let users approve actions.
| Event | Purpose |
|---|---|
TOOL_CALL_START |
Agent is invoking a tool. Contains tool name and call ID. |
TOOL_CALL_ARGS |
Streams the tool call arguments incrementally (useful for large payloads). |
TOOL_CALL_END |
Tool call arguments are complete. |
The frontend can render tool calls in real time – showing the user “Agent is calling search_database with query: …” before the call even completes. This transparency matters for enterprise trust.
4. State Management Events
These synchronize agent-side state with the frontend using a snapshot-delta pattern.
| Event | Purpose |
|---|---|
STATE_SNAPSHOT |
Full state object sent at the start or after major changes. |
STATE_DELTA |
Incremental JSON patch updating specific fields. Efficient for ongoing sync. |
This is powerful for collaborative UIs where the agent maintains structured state (e.g., a form being filled, a document being edited, a workflow progressing). The frontend renders the current state and applies deltas in real time.
5. Special Events
| Event | Purpose |
|---|---|
INTERRUPT |
Pauses agent execution to request human input or approval. Critical for human-in-the-loop patterns – “Agent wants to send this email. Approve?” |
CUSTOM |
Application-specific events for use cases not covered by standard types. |
RAW |
Passthrough events from external systems integrated into the agent pipeline. |
Event Stream Example
A typical agent run might produce this event sequence:
1
2
3
4
5
6
7
8
9
10
11
12
13
{"type": "RUN_STARTED", "threadId": "t-123", "runId": "r-456"}
{"type": "STEP_STARTED", "stepName": "research"}
{"type": "TEXT_MESSAGE_START", "messageId": "m-1", "role": "assistant"}
{"type": "TEXT_MESSAGE_CONTENT", "messageId": "m-1", "delta": "Based on the "}
{"type": "TEXT_MESSAGE_CONTENT", "messageId": "m-1", "delta": "latest data, "}
{"type": "TEXT_MESSAGE_CONTENT", "messageId": "m-1", "delta": "here are the findings:"}
{"type": "TEXT_MESSAGE_END", "messageId": "m-1"}
{"type": "TOOL_CALL_START", "toolCallId": "tc-1", "toolCallName": "query_database"}
{"type": "TOOL_CALL_ARGS", "toolCallId": "tc-1", "delta": "{\"query\": \"SELECT ...\"}" }
{"type": "TOOL_CALL_END", "toolCallId": "tc-1"}
{"type": "STATE_DELTA", "delta": [{"op": "replace", "path": "/status", "value": "complete"}]}
{"type": "STEP_FINISHED", "stepName": "research"}
{"type": "RUN_FINISHED", "runId": "r-456"}
Code Examples
React Integration with CopilotKit
CopilotKit provides the reference React implementation for AG-UI. The two primary hooks:
useAgent – direct AG-UI protocol access with full control:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { useAgent } from "@copilotkit/react-core";
function AgentPanel() {
const { messages, run, state, isRunning } = useAgent({
name: "research-agent",
agent: {
url: "https://agent-backend.example.com/ag-ui",
},
});
return (
<div>
{messages.map((msg) => (
<div key={msg.id}>{msg.content}</div>
))}
<button onClick={() => run("Analyze Q1 revenue trends")} disabled={isRunning}>
Run Agent
</button>
</div>
);
}
useCoAgent – higher-level abstraction for bidirectional state sharing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { useCoAgent } from "@copilotkit/react-core";
function CollaborativeEditor() {
const { state, setState, run } = useCoAgent({
name: "writing-assistant",
initialState: { draft: "", suggestions: [] },
});
// Agent and frontend share state bidirectionally.
// Agent emits STATE_DELTA events to update `state`.
// Frontend calls `setState` to push changes back to the agent.
return (
<textarea
value={state.draft}
onChange={(e) => setState({ ...state, draft: e.target.value })}
/>
);
}
Python Agent Backend (Framework-Agnostic)
Any Python agent can serve AG-UI events. Here is a minimal FastAPI example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import json, time
app = FastAPI()
async def agent_event_stream(user_message: str):
yield f"data: {json.dumps({'type': 'RUN_STARTED', 'runId': 'r-1'})}\n\n"
yield f"data: {json.dumps({'type': 'TEXT_MESSAGE_START', 'messageId': 'm-1', 'role': 'assistant'})}\n\n"
# Stream tokens from your LLM
for chunk in call_llm(user_message):
yield f"data: {json.dumps({'type': 'TEXT_MESSAGE_CONTENT', 'messageId': 'm-1', 'delta': chunk})}\n\n"
yield f"data: {json.dumps({'type': 'TEXT_MESSAGE_END', 'messageId': 'm-1'})}\n\n"
yield f"data: {json.dumps({'type': 'RUN_FINISHED', 'runId': 'r-1'})}\n\n"
@app.post("/ag-ui")
async def run_agent(request: RunAgentInput):
return StreamingResponse(
agent_event_stream(request.messages[-1].content),
media_type="text/event-stream",
)
Key Concepts
Human-in-the-Loop via INTERRUPT
The INTERRUPT event is what makes AG-UI more than a streaming protocol. When an agent hits a decision point that requires human approval (sending an email, making a purchase, deploying code), it emits an INTERRUPT event and pauses execution. The frontend renders an approval UI. The user’s response is sent back to the agent, which resumes. This pattern is essential for enterprise AI where autonomous agent actions carry real business risk.
State Synchronization (Snapshot-Delta)
AG-UI uses a pattern borrowed from real-time collaborative systems: send a full STATE_SNAPSHOT initially, then apply incremental STATE_DELTA patches (JSON Patch format) for ongoing updates. This is efficient – the agent doesn’t resend the entire state on every change – and it enables frontends to render complex, structured state (forms, workflows, dashboards) that update in real time.
Framework Agnostic by Design
AG-UI has official adapters for LangGraph, CrewAI, AG2 (AutoGen), Mastra, and the CopilotKit native runtime. The protocol itself is just JSON events over HTTP – any agent framework can implement an AG-UI endpoint by emitting the right events in the right order.
Comparison with Related Protocols
| Aspect | AG-UI | MCP | A2A |
|---|---|---|---|
| What connects | Agent backend to frontend UI | Agent to tools/data | Agent to agent |
| Direction | Agent streams to UI; user sends messages back | Agent calls tool, tool returns result | Bidirectional agent communication |
| Transport | SSE, WebSocket | stdio, HTTP SSE | HTTP, JSON-RPC 2.0 |
| State model | Snapshot + delta sync | Stateless tool calls | Stateful task lifecycle |
| Human involvement | Core design goal (INTERRUPT events) | None (machine-to-machine) | Optional (agent can request human input via client) |
| Key primitive | Event stream | Tool call | Task |
| Spec format | JSON event types | JSON-RPC | JSON-RPC |
AG-UI is complementary to both MCP and A2A. A production system uses all three: AG-UI for the user-facing layer, A2A for inter-agent orchestration, and MCP for tool/data access.
Current Adoption and Maturity
Production Adopters
- AWS Bedrock AgentCore added native AG-UI support in March 2026. AgentCore Runtime handles authentication, session isolation, and auto-scaling for AG-UI workloads. Available in 14 AWS regions. This was a major validation – AWS chose AG-UI over building a proprietary streaming protocol.
- Microsoft Agent Framework (the Semantic Kernel + AutoGen convergence) integrated AG-UI as one of three pillars in its “Golden Triangle” of agentic development: AG-UI for user interaction, DevUI for developer tooling, and OpenTelemetry for observability. Agent Framework 1.0 GA shipped end of Q1 2026 with AG-UI support in both .NET and Python.
- CopilotKit is the reference implementation. Their React SDK (
@copilotkit/react-core) providesuseAgentanduseCoAgenthooks that speak AG-UI natively.
Framework Adapters
Official AG-UI adapters exist for: LangGraph, CrewAI, AG2 (AutoGen), Mastra, Pydantic AI, and the CopilotKit runtime. Community adapters are emerging for additional frameworks.
Maturity Assessment
AG-UI is past the experimental phase. With AWS and Microsoft adopting it in production services, it has crossed the credibility threshold for enterprise use. The spec is still evolving (event types may be added), but the core event schema is stable. For any new project that needs to connect an agent backend to a frontend, AG-UI is the clear default choice – there is no serious competing open standard for this layer.
Spec Links
- Specification docs: https://docs.ag-ui.com
- GitHub: https://github.com/ag-ui-protocol/ag-ui
- CopilotKit integration: https://www.copilotkit.ai/ag-ui
- AWS Bedrock AgentCore AG-UI: https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-agui.html
- Microsoft Agent Framework AG-UI: https://learn.microsoft.com/en-us/agent-framework/integrations/ag-ui/