MCP应用服务器

MCP服务器模板与OpenAI Apps SDK集成,用于兼容ChatGPT的小部件。
特性
- 🤖 OpenAI应用软件开发工具包:与ChatGPT小部件完全兼容
- 🎨 官方UI组件:集成 OpenAI Apps SDK UI组件 用于一致、可访问的小部件
- 🛒 电子商务小工具:完整的电子商务示例,包括旋转木马、搜索、地图和订单确认
- 🔄 自动配准:小部件自动注册
resources/文件夹 - 📦 Props架构:小部件道具的Zod模式验证
- 🌙 主题支持:通过暗/亮主题检测
useWidget钩子 - 🛠️ TypeScript:完全类型安全
- 🔧 小部件功能:全力支持
callTool,sendFollowUpMessage,以及持久状态
新增功能:Apps SDK集成
此模板演示了如何使用OpenAI的Apps SDK构建与ChatGPT兼容的小部件:
import { useWidget } from 'mcp-use/react';
const MyWidget: React.FC = () => {
const { props, theme } = useWidget();
// props contains validated inputs from OpenAI
// theme is 'dark' or 'light' based on ChatGPT setting
}入门指南
发展
# Install dependencies
npm install
# Start development server
npm run dev这将开始:
- 端口3000上的MCP服务器
- 小工具服务于
/mcp-use/widgets/* - 检查器UI位于
/inspector
生产
# Build the server and widgets
npm run build
# Run the built server
npm start项目结构
mcp-apps/
├── resources/ # React widget components
│ ├── display-weather.tsx # Weather widget example
│ ├── ecommerce-carousel.tsx # Ecommerce product carousel
│ ├── product-search-result.tsx # Product search with filters
│ ├── stores-locations-map.tsx # Store locations map
│ └── order-confirmation.tsx # Order confirmation widget
├── index.ts # Server entry point (includes brand info tool)
├── package.json
├── tsconfig.json
└── README.md自动注册的工作原理
所有React组件 resources/ 导出时,文件夹会自动注册为MCP工具和资源 widgetMetadata:
import { z } from 'zod';
import type { WidgetMetadata } from 'mcp-use/react';
const propSchema = z.object({
city: z.string().describe('The city name'),
temperature: z.number().describe('Temperature in Celsius'),
});
export const widgetMetadata: WidgetMetadata = {
description: 'My widget description',
props: propSchema,
};
const MyWidget: React.FC = () => {
const { props } = useWidget>();
// Your widget implementation
};
export default MyWidget;这会自动创建:
- 工具:
display-weather-通过OpenAI接受参数 - 资源:
ui://widget/display-weather-静态访问
使用Apps SDK构建小部件
使用 useWidget 钩子
import { useWidget } from 'mcp-use/react';
interface MyProps {
title: string;
count: number;
}
const MyWidget: React.FC = () => {
const { props, theme, isPending } = useWidget();
// IMPORTANT: Widgets render before tool execution completes
// Always check isPending to handle the loading state
if (isPending) {
return
Loading...
;
}
// Now props are safely available
// props are validated and typed based on your schema
// theme is automatically set by ChatGPT
return (
{props.title}
Count: {props.count}
);
};备注:小部件在工具执行完成之前呈现。在第一次渲染时,props将为空{}和isPending将是true。始终检查isPending在使用道具之前。请参阅 小部件生命周期文档 了解更多详情。
定义小部件元数据
使用Zod模式定义小部件输入:
import { z } from 'zod';
import type { WidgetMetadata } from 'mcp-use/react';
const propSchema = z.object({
name: z.string().describe('Person name'),
age: z.number().min(0).max(120).describe('Age in years'),
email: z.string().email().describe('Email address'),
});
export const widgetMetadata: WidgetMetadata = {
description: 'Display user information',
props: propSchema,
};主题支持
自动适应ChatGPT的主题:
const { theme } = useWidget();
const bgColor = theme === 'dark' ? 'bg-gray-900' : 'bg-white';
const textColor = theme === 'dark' ? 'text-gray-100' : 'text-gray-800';官方UI组件
此模板使用 OpenAI Apps SDK UI组件库 用于构建一致、可访问的小部件。图书馆提供:
- 按钮:主要、次要和轮廓按钮变体
- 卡:内容部分的容器组件
- 旋转木马:带有过渡的图像和内容轮播
- 输入:表单输入字段
- 图标:一致的图像
- 过渡:平滑的动画和过渡
导入以下组件:
import {
Button,
Card,
Carousel,
CarouselItem,
Transition,
Icon,
Input,
} from '@openai/apps-sdk-ui';电子商务小工具
此模板包括一个完整的电子商务示例,其中包含四个小部件:
1.电子商务旋转木马(ecommerce-carousel.tsx)
产品转盘小部件具有以下特点:
- 标题和说明
- 带有占位符图像的产品项目旋转木马
- 每个商品的“信息”按钮和“添加到购物车”按钮
- 使用官方旋转木马、卡片、按钮、图标和过渡组件
- 与集成
callTool用于推车操作 - 持续状态管理
2.产品搜索结果(product-search-result.tsx)
搜索结果小部件,包括:
- 具有实时过滤功能的搜索输入
- 价格范围过滤器和库存状态过滤器
- 产品卡片网格布局
- 用途
callTool执行搜索 - 用途
sendFollowUpMessage更新对话 - 持久过滤器状态
3.店铺位置图(stores-locations-map.tsx)
商店定位器小部件具有以下功能:
- 交互式地图显示(占位符)
- 店铺位置列表及详细信息
- 距离计算
- 获取方向功能
- 点击商店详细信息
- 用途
callTool获取路线和店铺信息
4.订单确认(order-confirmation.tsx)
订单确认小部件,包括:
- 订单摘要和项目列表
- 运输信息
- 订单状态跟踪
- 跟踪订单并查看收货操作
- 用途
callTool用于订单跟踪
品牌信息工具
该模板包括 get-brand-info 返回品牌信息的工具(普通MCP工具,不是小部件):
// Call the tool
await client.callTool('get-brand-info', {});
// Returns brand details including:
// - Company name, tagline, description
// - Mission and values
// - Contact information
// - Social media links示例:天气小工具
包括 display-weather.tsx 小部件演示:
- 架构定义:用于验证的Zod模式
- 元数据导出:小部件注册信息
- 主题检测:暗/亮模式支持
- 类型安全:完全支持TypeScript
// Get props from OpenAI Apps SDK
const { props, theme } = useWidget();
// props.city, props.weather, props.temperature are validated在ChatGPT中使用小部件
通过工具调用
await client.callTool('display-weather', {
city: 'San Francisco',
weather: 'sunny',
temperature: 22
});通过资源访问
await client.readResource('ui://widget/display-weather');定制指南
添加新小部件
- 在中创建一个React组件
resources/my-widget.tsx:
import React from 'react';
import { z } from 'zod';
import { useWidget, type WidgetMetadata } from 'mcp-use/react';
const propSchema = z.object({
message: z.string().describe('Message to display'),
});
export const widgetMetadata: WidgetMetadata = {
description: 'Display a message',
props: propSchema,
};
type Props = z.infer;
const MyWidget: React.FC = () => {
const { props, theme } = useWidget
();
return (
{props.message}
);
};
export default MyWidget;- 该小部件已自动注册!
添加传统MCP工具
您可以将Apps SDK小部件与常规MCP工具混合使用:
import { text } from 'mcp-use/server';
server.tool({
name: 'get-data',
description: 'Fetch data from API',
cb: async () => {
return text('Data');
},
});测试您的小部件
通过检查器UI
- 启动服务器:
npm run dev - 打开:
http://localhost:3000/inspector - 交互式测试小部件
直接浏览器访问
访问: http://localhost:3000/mcp-use/widgets/display-weather
通过MCP客户端
import { createMCPClient } from 'mcp-use/client';
const client = createMCPClient({
serverUrl: 'http://localhost:3000/mcp',
});
await client.connect();
// Call widget as tool
const result = await client.callTool('display-weather', {
city: 'London',
weather: 'rain',
temperature: 15
});应用程序SDK与其他小部件类型
| 功能 | 应用程序SDK | 外部URL | 远程DOM |
|---|---|---|---|
| ChatGPT兼容 | ✅ 是 | ❌ 否 | ❌ 没有 |
| 主题检测 | ✅ 自动 | ❌ 手册 | ❌ 手册 |
| 道具验证 | ✅ Zod架构 | ❌ 手册 | ❌ 手册 |
| React支持 | ✅ 已满 | ✅ 已满 | ❌ 有限 |
| OpenAI元数据 | ✅ 是 | ❌ 否 | ❌ 没有 |
Apps SDK的好处
✅ ChatGPT原生 -在ChatGPT中无缝工作 ✅ 主题感知 -自动暗/亮模式 ✅ 类型安全 -带有Zod验证的完整TypeScript ✅ 简单API -所有道具都有一个钩子 ✅ 自动注册 -导出元数据并完成
故障排除
小部件未加载
- 确保小部件具有
widgetMetadata出口 - 检查Zod架构是否有效
- 验证小部件是否存在于
dist/resources/mcp-use/widgets/
道具未通过
- 确保架构包括所有道具
- 检查
.describe()对于每个道具 - 验证
useWidget钩子被称为
主题未应用
- 主题仅在ChatGPT中可用
- 使用
theme从useWidget()钩子 - 在实际ChatGPT接口中测试
从其他模板迁移
从移动 starter 到 mcp-apps:
// Before: Manual props handling
const params = new URLSearchParams(window.location.search);
const city = params.get('city');
// After: Apps SDK hook
const { props } = useWidget();
const city = props.city;使用小部件功能
此模板中的小部件展示了Apps SDK的全部功能:
呼叫工具(callTool)
小部件可以调用其他MCP工具:
const { callTool } = useWidget();
const handleAction = async () => {
const result = await callTool('add-to-cart', {
productId: '123',
productName: 'Product Name',
price: 29.99
});
};发送后续消息(sendFollowUpMessage)
小部件可以向ChatGPT对话发送消息:
const { sendFollowUpMessage } = useWidget();
await sendFollowUpMessage('Product added to cart successfully!');持续状态(setState)
小部件可以在交互中保持状态:
const { setState, state } = useWidget();
// Save state
await setState({ cart: [...cart, newItem] });
// Read state
const savedCart = state?.cart || [];组件库注释
如果官方库不可用,您可以用自定义React组件或其他UI库替换导入,同时保持相同的小部件结构。
了解更多
快乐建筑! 🚀
