Remote agents (A2A & AG-UI)
Moka doesn’t have to call a model directly. Point a workspace at an agent and Moka becomes its front end: streaming chat, A2UI rendering, tool cards, approvals and a full event trace in the inspector.
| Protocol | Good for | Conversation state |
|---|---|---|
| A2A (Agent2Agent) | Agents that publish an agent card: Google ADK, A2A SDK agents, many enterprise agents | Kept by the agent (Moka sends contextId / taskId) |
| AG-UI | LangGraph, CopilotKit, Mastra, Pydantic AI, CrewAI… | Sent by Moka every turn (full history + agent state) |
Try it in a minute
Section titled “Try it in a minute”-
Start the bundled demo agent. It speaks both protocols:
Terminal window npx @mokalabs/sandbox demo-agent # A2A card on :4100, AG-UI at /agui -
In Moka, open Settings → Agents → Connect an agent and pick Moka demo agent · A2A (or AG-UI).
-
Choose it in the model menu in the top bar (agents are listed under the models), and ask “book a tasting”.
You’ll get an A2UI booking form from the agent. Pressing Book it sends the action back to the agent, which confirms the booking.
Configure
Section titled “Configure”{ "agents": [ { "id": "support", "name": "Support agent", "protocol": "a2a", "url": "https://agents.example.com/support/.well-known/agent-card.json", "headers": { "Authorization": "Bearer ${SUPPORT_AGENT_TOKEN}" } }, { "id": "research", "name": "Research graph", "protocol": "ag-ui", "url": "http://localhost:8000/agent", "shareTools": true } ], "workspaces": [ { "id": "demo", "name": "Support demo", "agentId": "support", "mcpServerIds": [], "skillIds": [] } ]}| Field | |
|---|---|
protocol | a2a or ag-ui |
url | A2A: the agent card URL (Moka reads the endpoint from it) or the JSON-RPC endpoint itself. AG-UI: the URL you POST RunAgentInput to |
headers | Extra request headers; values support env:NAME and ${NAME} |
shareTools | AG-UI only: offer the workspace’s MCP tools and render tool as frontend tools (below) |
A workspace uses its agentId instead of llmId. Test in the agent form shows the agent card (skills, streaming, A2UI support) or a short AG-UI run.
Moka sends message/stream (SSE), or message/send when the card says the agent doesn’t stream, and renders:
- Text from agent messages, status updates and streamed artifacts.
- A2UI from DataParts (
mimeType: application/json+a2ui). Moka activates the A2UI extension with theX-A2A-Extensionsheader when the card declares it. - Other data parts as expandable JSON cards, and file parts as links.
Button presses on A2UI surfaces go back as a DataPart: { "version": "v0.9", "action": {…}, "userAction": {…} }. Attachments are sent as FileParts. The contextId (and taskId while a task is input-required) is carried across turns automatically.
Moka POSTs RunAgentInput (thread id, full message history, agent state, tools) and reads the event stream:
TEXT_MESSAGE_*→ streaming text,THINKING_*/REASONING_*→ reasoningTOOL_CALL_*andTOOL_CALL_RESULT→ tool cardsSTATE_SNAPSHOT/STATE_DELTA→ agent state, sent back on the next turnCUSTOM,ACTIVITY_SNAPSHOTorRAWevents that carry A2UI → rendered surfacesRUN_ERROR→ an error in the chat
A2UI button presses arrive as a [ui action] {…} user message.
Give an AG-UI agent your MCP tools
Section titled “Give an AG-UI agent your MCP tools”With shareTools, the workspace’s MCP tools (and the render tool) are sent as AG-UI frontend tools. When the agent calls one:
- Moka runs it against the MCP server, with approvals if they apply.
- The result is added to the history as a tool message, and the run continues automatically.
So a LangGraph agent in development can use GitHub, your filesystem or your company’s MCP servers without any wiring in the agent.
Inspector
Section titled “Inspector”Agent runs show up as agent.request (what Moka sent), agent.event (each A2A result or AG-UI event) and agent.response, plus the usual tool.* events for frontend tools.