AG-UI Protocol: Streaming Agent Execution to the Frontend

~15 min read

AG-UI standardizes the missing third leg of the agent stack — Agent-to-User communication — using Server-Sent Events to stream structured events like token generation and tool-call progress to any frontend.

MCP standardized Agent-to-Tool communication, and A2A standardized Agent-to-Agent communication. But there's one piece still missing: a protocol for Agent-to-USER communication. Understanding why this gap matters requires seeing the real problem it causes.

You can build powerful multi-step agentic workflows using a toolkit like LangGraph, CrewAI, or Mastra — but the moment you try to bring that agent into a real-world app, things fall apart. You want to stream LLM responses token by token without building a custom WebSocket server. You want to display tool execution progress as it happens, and pause for human feedback without losing context. You want to sync large, changing objects (like code or tables) without re-sending everything to the UI on every update. And you want users to interrupt, cancel, or reply mid-run without losing context. On top of all that: every agent backend has its OWN mechanisms for tool calling, planning, and output formats — building for LangGraph means custom WebSocket logic and UI adapters specific to LangGraph, and migrating to CrewAI means redoing all of it. This doesn't scale.

AG-UI (Agent-User Interaction Protocol), an open-source protocol by CopilotKit, solves this by standardizing the interaction layer between backend agents and frontend UIs. Think of it this way: just like REST is the standard for client-to-server requests, AG-UI is the standard for streaming real-time agent updates back to the UI. Technically, it uses Server-Sent Events (SSE) to stream structured JSON events to the frontend, each with an explicit payload — TEXT_MESSAGE_CONTENT for token streaming, TOOL_CALL_START to show tool execution progress, STATE_DELTA to update shared state incrementally (not full re-sends), and AGENT_HANDOFF to smoothly pass control between agents.

The payoff: write your backend logic once and hook it into AG-UI, and it just works — LangGraph, CrewAI, and Mastra can all emit AG-UI events, UIs can be built with CopilotKit components or a custom React stack, and you can swap the underlying model (GPT-4 for a local Llama-3) without touching the frontend at all. This is exactly the layer that makes agent apps feel like real, responsive software rather than glorified chatbots.

💻 Code example

# Conceptual AG-UI event stream — structured SSE events with explicit
# payloads, standardized regardless of which agent framework emits them.
import json

def ag_ui_event(event_type: str, payload: dict) -> str:
    """Format a single AG-UI SSE event — the same shape whether the
    backend is LangGraph, CrewAI, or Mastra."""
    return f"data: {json.dumps({'type': event_type, 'payload': payload})}\n\n"

async def stream_agent_run(agent_response_chunks, tool_calls):
    # Token-by-token streaming — no custom WebSocket server needed
    for chunk in agent_response_chunks:
        yield ag_ui_event("TEXT_MESSAGE_CONTENT", {"delta": chunk})

    # Tool execution progress, visible to the UI as it happens
    for tool_call in tool_calls:
        yield ag_ui_event("TOOL_CALL_START", {"name": tool_call["name"], "args": tool_call["args"]})

    # Incremental state updates — not a full re-send of a large object
    yield ag_ui_event("STATE_DELTA", {"path": "code.py", "diff": "+ print('done')"})

# Any frontend speaking AG-UI (CopilotKit components, custom React, etc.)
# can consume this exact event stream regardless of the backend framework

💬 Deep Dive with AI

Key points

  • AG-UI fills the missing third leg of the agent stack: Agent-to-User communication (MCP=tools, A2A=other agents, AG-UI=the user's UI)
  • The problem it solves: every agent backend has its own tool-calling/streaming mechanisms, making UI integration framework-specific and unscalable
  • AG-UI uses Server-Sent Events (SSE) to stream structured JSON events with explicit payloads
  • Key event types: TEXT_MESSAGE_CONTENT (token streaming), TOOL_CALL_START, STATE_DELTA (incremental state updates), AGENT_HANDOFF
  • Write backend logic once, hook into AG-UI, and swap frameworks or models without touching the frontend