🧩 架构概述
此概念验证演示了使用MCP UI、OpenAI和远程DOM渲染管道构建的端到端AI驱动的购物体验。 该系统使用LLM动态生成UI布局和产品结果,然后在React应用程序中安全地呈现它们。
核心组件
1.MCP用户界面客户端(@MCP用户界面/客户端)
MCP UI客户端在React应用程序中用于呈现服务器动态生成的UI。 主要特点:
使用渲染UI资源
支持远程DOM,其中DOM节点由服务器或LLM定义
映射自定义远程DOM元素(例如。, , , )React组件
使用onUIAction处理远程事件(例如,addToArt、removeFromCart)
这允许在运行时构建复杂的UI,而无需将UI代码从服务器运送到客户端。
资源呈现器 UI资源在 组件。它会自动检测资源类型并呈现相应的组件。 它接受以下道具:
resource:MCP工具响应中的资源对象。它必须包含uri、mimeType和内容(文本、blob)
onUIAction:用于处理来自资源的UI操作的可选回调
remoteDomProps:内部可选道具
library:用于远程DOM资源的React组件库
remoteElements:远程DOM资源的远程元素定义。
2.MCP UI服务器(@MCP UI/Server)
后端使用MCP UI Server实用程序创建前端可以呈现的UI资源。 责任:
使用createUIResource()包装生成的远程DOM脚本
提供一致的编码和元数据
与MCP UI客户端无缝集成
服务器不发送HTML,而是发送前端通过远程DOM层呈现的指令。
创建UI资源
从服务器返回给客户端的主要有效负载是UIResource:
createUIResource({
uri: `ui://cart/${Date.now()}`,
content: {
type: 'remoteDom',
script: script,
framework: 'react'
},
encoding: 'text'
});uri:缓存和路由的唯一标识符
type:UI资源类型
script:远程dom脚本+数据作为JavaScript变量
framework:用React开发的自定义组件UI库
encoding:“text”或“blob”(如果是编码内容)
🌐 远程DOM
远程DOM是动态UI的基础。 服务器(和LLM)不发送HTML或JSX,而是发送一个在沙盒环境中执行的JavaScript脚本,并使用自定义元素构建虚拟DOM树,例如:
``
``
``
``
``
``
每个元素对应一个在远程DOM组件库中实现的React组件。
脚本中的事件处理程序分派CustomEvents,客户端将其映射到onUIAction事件,以便React应用程序响应。
这可以实现完全生成的UI布局,如产品搜索结果、购物车页面等。
🤖 OpenAI集成
OpenAI主要有两种使用方式:
A.产品生成
OpenAI综合了真实的产品数据集:
`name`
`description`
`price`
`currency`
`imageUrl`
`tags`这些产品被插入到Postgres中,因此未来的搜索将使用语义检索。
B.远程DOM UI生成
OpenAI生成JavaScript远程DOM脚本,描述UI应该如何查找:
搜索结果页面
购物车页面
愿望清单页面
此脚本缓存在Postgres中,以避免重复的LLM调用。
该系统结合了:
LLM推理→ UI布局
LLM创意→ 产品生成
确定性业务逻辑→ 购物车/愿望清单更新
🗄️ PostgreSQL
Postgres充当核心持久存储层。 表格包括:
产品
存储OpenAI生成的或通过矢量存储搜索的所有产品元数据。
cart_items和wishlist_items
维护用户特定的购物状态:
购物车中的商品
数量
愿望清单项目
原始搜索提示
remote_dom_cache
缓存LLM生成的远程DOM脚本,因此UI不需要重复调用OpenAI。
Postgres确保数据模型的一致性、唯一性和结构完整性。
🚀 端到端流程摘要
用户搜索→ React应用程序调用/搜索
OpenAI推出新产品
服务器请求OpenAI创建远程DOM脚本
脚本缓存在Postgres中
服务器返回UIResource
React使用MCP UI客户端+远程DOM库进行渲染
用户操作(添加/删除)触发远程事件
服务器相应地更新Postgres
购物车/愿望清单屏幕也由LLM Remote DOM生成
服务器应用程序接口
http://localhost:8082/search
Step 1: Search for relevant products
Step 2: Try to load cached remote DOM script (from PostgreSQL)
Step 3: If not available, then ask LLM to generate Remote DOM JS ONLY
Step 4: Store script in DB prepared by LLM
Step 5: Combine the Product searched and the script into the final script
Step 6: Wrap the final script in the MCP-UI resource and respondhttp://localhost:8082/cart-ui
Step 1: Find cart and wishlist items from the database
Step 2: Try to load cached remote DOM script (from PostgreSQL)
Step 3: If not available, then ask LLM to generate Remote DOM JS ONLY
Step 4: Store the script in the DB prepared by LLM
Step 5: Combine cart and wishlist items and script into the final script
Step 6: Wrap the final script in the MCP-UI resource and respondPostgres SQL查询
CREATE TABLE IF NOT EXISTS remote_dom_cache (
id SERIAL PRIMARY KEY,
cache_key TEXT NOT NULL UNIQUE,
script TEXT NOT NULL,
model TEXT,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_dom_cache_key
ON remote_dom_cache (cache_key);
CREATE TABLE IF NOT EXISTS cart_items (
id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL,
product_id TEXT NOT NULL,
from_prompt TEXT,
qty INTEGER NOT NULL DEFAULT 1,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_cart_items_user_id
ON cart_items (user_id);
CREATE TABLE IF NOT EXISTS wishlist_items (
id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL,
product_id TEXT NOT NULL,
from_prompt TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_wishlist_items_user_id
ON wishlist_items (user_id);
CREATE TABLE IF NOT EXISTS products (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
price INTEGER NOT NULL,
currency TEXT NOT NULL,
image_url TEXT,
tags TEXT[],
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);--产品表链接(可选但推荐)
ALTER TABLE cart_items
ADD CONSTRAINT fk_cart_items_product
FOREIGN KEY (product_id) REFERENCES products(id);--确保每个(用户、产品)一行
CREATE UNIQUE INDEX IF NOT EXISTS idx_cart_items_user_product
ON cart_items (user_id, product_id);
ALTER TABLE wishlist_items
ADD CONSTRAINT wishlist_items_user_product_unique
UNIQUE (user_id, product_id);--产品表链接(可选但推荐)
ALTER TABLE wishlist_items
ADD CONSTRAINT fk_wishlist_items_product
FOREIGN KEY (product_id) REFERENCES products(id);