Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions samples/agent/adk/mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from starlette.requests import Request
from a2ui.extension.a2ui_schema_utils import wrap_as_json_array

A2UI_MCP_MESSAGES_KEY = "messages"


def load_a2ui_schema() -> dict[str, Any]:
current_dir = pathlib.Path(__file__).resolve().parent
Expand Down Expand Up @@ -80,7 +82,7 @@ def main(port: int, transport: str) -> int:
@app.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any]) -> dict[str, Any]:
if name == "get_recipe_a2ui":
return {"events": recipe_a2ui_json}
return {A2UI_MCP_MESSAGES_KEY: recipe_a2ui_json}

if name == "send_a2ui_user_action":
return {"response": f"Received A2UI user action", "args": arguments}
Expand All @@ -102,8 +104,8 @@ async def list_tools() -> list[types.Tool]:
# TODO fix this in MCP SDK
outputSchema={
"type": "object",
"properties": {"events": a2ui_schema},
"required": ["events"],
"properties": {A2UI_MCP_MESSAGES_KEY: a2ui_schema},
"required": [A2UI_MCP_MESSAGES_KEY],
"additionalProperties": False,
},
),
Expand Down
42 changes: 41 additions & 1 deletion specification/v0_10/docs/a2ui_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,51 @@ A2A is uniquely capable of handling remote agent communication, and can also pro
**[AG-UI](https://docs.ag-ui.com/introduction)** is also an excellent transport option for A2UI Agent–User Interaction protocol.
AG UI provides convenient integrations into many agent frameworks and frontends. AG UI provides low latency and shared state message passing between front ends and agentic backends.

#### MCP (Model Context Protocol) binding

A2UI over MCP uses a single JSON object payload, transported through MCP tool results or MCP resources.

- **Message container**: The canonical payload shape is an object with a `messages` field.
- **Schema binding**:
- For server-to-client UI updates, `messages` MUST validate against [server_to_client_list.json](../json/server_to_client_list.json).
- For client-to-server events, `messages` MUST validate against [client_to_server_list.json](../json/client_to_server_list.json).
Comment on lines +116 to +117
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with other schema links in this document (like [a2ui_client_capabilities.json]), it would be better to use reference-style links here. This would make all schema links follow the same pattern.

Here is the suggested change:

  - For server-to-client UI updates, `messages` MUST validate against [`server_to_client_list.json`].
  - For client-to-server events, `messages` MUST validate against [`client_to_server_list.json`].

You'll also need to add the corresponding definitions at the end of the file:

[`server_to_client_list.json`]: ../json/server_to_client_list.json
[`client_to_server_list.json`]: ../json/client_to_server_list.json

- **Aggregation and ordering**: `messages` is an ordered batch. Receivers MUST process messages in order.
- **Error handling**: If a message in the batch fails validation or application, receivers SHOULD report/log that message-level failure and SHOULD continue processing later messages in the same batch.
- **Tool vs. resource usage**:
- Use MCP **tools** for request/response flows (initial render requests and user actions).
- Use MCP **resources** (including subscriptions/updates) for long-lived UI surfaces that are updated over time.
- **Post-creation updates**: UIs remain mutable after first render. Additional batches MAY contain `updateComponents`, `updateDataModel`, and `deleteSurface` for previously created `surfaceId`s.
- **Catalog negotiation**: Before the first `createSurface`, clients MUST provide `a2uiClientCapabilities` that conform to [`a2ui_client_capabilities.json`]. Servers MUST choose a compatible catalog and set it in `createSurface.catalogId`.

Example MCP payload:

```json
{
"messages": [
{
"version": "v0.10",
"createSurface": {
"surfaceId": "main",
"catalogId": "https://a2ui.org/specification/v0_10/standard_catalog.json"
}
},
{
"version": "v0.10",
"updateComponents": {
"surfaceId": "main",
"components": [
{ "id": "root", "component": "Text", "text": "Hello from MCP" }
]
}
}
]
}
```

#### Other transports

A2UI can also be carried over:

- **[MCP (Model Context Protocol)](https://modelcontextprotocol.io/docs/getting-started/intro)**: Delivered as tool outputs or resource subscriptions.
- **[SSE](https://en.wikipedia.org/wiki/Server-sent_events) with [JSON RPC](https://www.jsonrpc.org/)**: Standard server-sent events for web integrations that support streaming, and JSON RPC for client-server communication.
- **[WebSockets](https://en.wikipedia.org/wiki/WebSocket)**: For bidirectional, real-time sessions.
- **[REST](https://cloud.google.com/discover/what-is-rest-api?hl=en)**: For simple use case, REST APIs will work but lack streaming capabilities.
Expand Down
42 changes: 41 additions & 1 deletion specification/v0_9/docs/a2ui_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,51 @@ A2A is uniquely capable of handling remote agent communication, and can also pro
**[AG-UI](https://docs.ag-ui.com/introduction)** is also an excellent transport option for A2UI Agent–User Interaction protocol.
AG UI provides convenient integrations into many agent frameworks and frontends. AG UI provides low latency and shared state message passing between front ends and agentic backends.

#### MCP (Model Context Protocol) binding

A2UI over MCP uses a single JSON object payload, transported through MCP tool results or MCP resources.

- **Message container**: The canonical payload shape is an object with a `messages` field.
- **Schema binding**:
- For server-to-client UI updates, `messages` MUST validate against [server_to_client_list.json](../json/server_to_client_list.json).
- For client-to-server events, `messages` MUST validate against [client_to_server_list.json](../json/client_to_server_list.json).
Comment on lines +121 to +122
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with other schema links in this document (like [a2ui_client_capabilities.json]), it would be better to use reference-style links here. This would make all schema links follow the same pattern.

Here is the suggested change:

  - For server-to-client UI updates, `messages` MUST validate against [`server_to_client_list.json`].
  - For client-to-server events, `messages` MUST validate against [`client_to_server_list.json`].

You'll also need to add the corresponding definitions at the end of the file:

[`server_to_client_list.json`]: ../json/server_to_client_list.json
[`client_to_server_list.json`]: ../json/client_to_server_list.json

- **Aggregation and ordering**: `messages` is an ordered batch. Receivers MUST process messages in order.
- **Error handling**: If a message in the batch fails validation or application, receivers SHOULD report/log that message-level failure and SHOULD continue processing later messages in the same batch.
- **Tool vs. resource usage**:
- Use MCP **tools** for request/response flows (initial render requests and user actions).
- Use MCP **resources** (including subscriptions/updates) for long-lived UI surfaces that are updated over time.
- **Post-creation updates**: UIs remain mutable after first render. Additional batches MAY contain `updateComponents`, `updateDataModel`, and `deleteSurface` for previously created `surfaceId`s.
- **Catalog negotiation**: Before the first `createSurface`, clients MUST provide `a2uiClientCapabilities` that conform to [`a2ui_client_capabilities.json`]. Servers MUST choose a compatible catalog and set it in `createSurface.catalogId`.

Example MCP payload:

```json
{
"messages": [
{
"version": "v0.9",
"createSurface": {
"surfaceId": "main",
"catalogId": "https://a2ui.org/specification/v0_9/standard_catalog.json"
}
},
{
"version": "v0.9",
"updateComponents": {
"surfaceId": "main",
"components": [
{ "id": "root", "component": "Text", "text": "Hello from MCP" }
]
}
}
]
}
```

#### Other transports

A2UI can also be carried over:

- **[MCP (Model Context Protocol)](https://modelcontextprotocol.io/docs/getting-started/intro)**: Delivered as tool outputs or resource subscriptions.
- **[SSE](https://en.wikipedia.org/wiki/Server-sent_events) with [JSON RPC](https://www.jsonrpc.org/)**: Standard server-sent events for web integrations that support streaming, and JSON RPC for client-server communication.
- **[WebSockets](https://en.wikipedia.org/wiki/WebSocket)**: For bidirectional, real-time sessions.
- **[REST](https://cloud.google.com/discover/what-is-rest-api?hl=en)**: For simple use case, REST APIs will work but lack streaming capabilities.
Expand Down