ChatGPT应用模板

一个用于构建和部署ChatGPT应用的模板,支持响应式React组件和与MCP服务器的交互。

  • by AjayiMike
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 AjayiMike/openai-apps-template

使用说明

Openai应用模板(todo APP)

构建、预览和发布一个ChatGPT应用程序,该应用程序呈现一个响应式的React小部件,并与模型上下文协议(MCP)服务器通信——所有这些都来自一个存储库。

  • 单文件小部件交付 –每个小部件都捆绑在 dist/<name>.html 使用内联JS+CSS,因此ChatGPT可以通过以下方式嵌入它 ui://widget/....
  • 电池包括MCP服务器 –公开SSE+POST端点,通告工具/资源,并返回结构化todo数据和小部件元数据。
  • 本地首个DX –带有HMR、Tailwind风格、React 19、TypeScript和反映ChatGPT的助手钩子的Vite开发服务器 window.openai 运行时。

使用此模板作为任何需要交互式UI和ChatGPT代理可以调用的工具的小型应用程序的起点。


一览

工件 技术 目的
src/widgets/todo.tsx React+hooks 交互式todo小部件,可以在与代理同步的同时乐观地更新本地状态
server.ts 节点+ @modelcontextprotocol/sdk 最小化MCP服务器暴露 todo list, add_todo, toggle_todo, delete_todo,以及小部件资源
build.ts Vite+esbuild 发现小部件条目,将其捆绑在一起,并生成准备好的内联HTML文件 ui://widget/...
dev.ts Vite loader 允许您通过以下方式热重新加载任何小部件 http://localhost:5173?entry=<name>

先决条件

  • Node.js 18+
  • npm(或者pnpm/yarn,如果你调整脚本的话)
  • (可选) 吸烟 或类似的隧道,与ChatGPT共享MCP服务器

安装依赖项:

npm install

快速开始

  1. 构建小部件包

    npm run build
    # → dist/todo.html (inline CSS + JS)
    
  2. 运行MCP服务器

    npm start
    # SSE  GET  http://localhost:8000/mcp
    # POST POST http://localhost:8000/mcp/messages?sessionId=...
    
  3. 在本地预览小部件(可选)

    npm run dev
    # open http://localhost:5173?entry=todo
    
  4. 暴露于ChatGPT(可选)

    ngrok http 8000
    # use https://<subdomain>.ngrok-free.app/mcp as the connector URL
    

开发流程

小部件迭代

  • 小工具位于 src/widgets/<name>.tsx。每个文件都应该调用 createRoot 并自行安装 __WIDGET_ROOT_ID__.
  • npm run dev 使用HMR启动Vite。引导到 http://localhost:5173?entry=<name> 加载该小部件。
  • 挂钩下 src/hooks 提供键入访问权限 window.openai 全局:
    • useWidgetProps 提取结构化工具输出(toolOutput.todoList 在这种情况下)。
    • useWidgetState 通过以下方式使本地小部件状态与ChatGPT主机保持同步 window.openai.setWidgetState.
    • useCallTool, useRequestDisplayMode等包装MCP API。
  • todo小部件显示 theme, safeArea.insets, displayMode,以及 maxHeight 因此,它可以匹配ChatGPT的亮/暗调色板,尊重安全区域,并根据PiP、内联或全屏布局调整自身大小,而无需您进行额外工作。

ChatGPT的构建

  • npm run build 自动发现中的每个文件 src/widgets (或嵌套 index.tsx 目录中的文件)并发出 dist/<name>.html.
  • 每个HTML文件内联:
    1. 共享顺风风格 src/styles/main.css
    2. 退路 window.todoData 独立预览块
    3. 缩小的小部件包
  • 构建脚本保持输出自包含,因此ChatGPT可以获取 ui://widget/<name>.html 没有额外的资产。

MCP服务器

  • server.ts 电线向上 @modelcontextprotocol/sdk 带着一个 SSEServerTransport:
    • GET /mcp 启动SSE会话。
    • POST /mcp/messages?sessionId=<id> 流工具消息/响应。
  • 默认情况下附带的工具:
    名称 描述 参数
    list_todos 返回当前待办事项列表 none
    add_todo_item 插入新待办事项 { title }
    toggle_todo_item 翻转完成状态 { todoId }
    delete_todo_item 删除待办事项 { todoId }
  • 所有工具响应包括:
    • structuredContent.todoList (反映小部件数据契约)
    • _meta.openai/* 描述符,以便ChatGPT知道如何呈现小部件
  • 服务器在内存中保存了一个简单的 globalTodoState.当你从演示毕业时,把它换成一个真正的数据库或API。

连接到ChatGPT应用程序

  1. 启用 开发者模式 在ChatGPT中→ 设置→ 连接器.

  2. 创建新的“模型上下文协议”连接器。

  3. 将MCP URL指向您的服务器(本地隧道或部署的主机):

    https://<your-ngrok-subdomain>.ngrok-free.app/mcp
    
  4. 在ChatGPT对话中,询问类似“显示我的待办事项列表”或“在我的待办事务中添加“审核PR”之类的问题。ChatGPT将调用相应的工具,小部件将使用 ui:// 服务器公开的资源。


项目结构

openai-apps-template/
├─ src/
│  ├─ widgets/
│  │  └─ todo/
│  │     ├─ index.tsx              # Widget entry point (self-mounting)
│  │     └─ components/
│  │        ├─ NewTodo.tsx         # Input row for creating todos
│  │        └─ TodoItem.tsx        # Presentational list item
│  ├─ hooks/              # window.openai + MCP helpers
│  ├─ styles/main.css     # Tailwind layer shared by widgets
│  └─ utils/              # UI utilities (media queries, etc.)
├─ build.ts               # Inline widget bundler
├─ dev.ts                 # Vite preview loader (?entry=<name>)
├─ server.ts              # MCP SSE server + todo tools
├─ dist/                  # Generated ui:// HTML widgets
├─ package.json
└─ README.md

脚本和配置

命令 描述
npm run build 将每个小部件捆绑到 dist/*.html
npm start 启动MCP服务器(默认为端口 8000)
npm run start:all 构建小部件,然后启动服务器
npm run dev 用于小部件HMR预览的Vite开发服务器

环境变量:

  • PORT –覆盖MCP服务器端口(默认 8000).

扩展模板

  • 添加另一个小部件:drop src/widgets/notes.tsx,确保其安装到 __WIDGET_ROOT_ID__,跑 npm run build,然后将其作为新的资源/工具公开 server.ts.
  • 保存待办事项数据:替换 globalTodoState 使用数据库调用或REST客户端。小部件需要的唯一合同是 { todoList: TodoList },在哪里 TodoList 只不过 { title: string; todos: TodoItem[] }.
  • 增强UI状态:使用 useWidgetState 乐观的更新;它已经将状态镜像回ChatGPT,因此主机在代理轮之间保持同步。
  • 添加更多工具:在中注册描述符 server.ts (ListToolsRequestSchema 处理程序)并在内部实现行为 CallToolRequest 处理程序。

故障排除

  • 小部件显示过时数据 –确保MCP响应包括新鲜 structuredContent.todoList 和 _meta.openai/outputTemplate。只有当主机发送新的结构化数据时,小部件才会重新同步。
  • “未找到构建”错误 –运行 npm run build 开始前 npm start 所以 dist/todo.html 存在。
  • ChatGPT中没有小部件 –验证连接器是否允许渲染小部件(openai/widgetAccessible: true)而且 ui://widget/<name>.html 资源通过以下方式列出 ListResources.
  • CORS或隧道问题 –服务器启用 Access-Control-Allow-Origin: *,但你的隧道必须同时向前 GET /mcp 和 POST /mcp/messages.

运输愉快!如果添加新的小部件、存储适配器或部署方案,则会出现未解决的问题或PR。