Todo MCP Server
ChatGPT Todo MCP 演示 (Apps SDK + React)
一个为 ChatGPT 设计的极简 todo 应用:一个 MCP 服务器,通过 React + Vite 构建并嵌入为单文件包,暴露了工具和一个交互式 HTML UI。包含一个简单的 开发 OAuth 层,以便 ChatGPT 的连接器向导可以完成发现过程。
官方参考:Apps SDK 快速入门。
快速开始
npm install
npm start # builds widget (prestart) then runs server on port 8787 by defaultMCP 端点:
http://localhost:8787/mcp对于 ChatGPT:使用 HTTPS 暴露(例如 ngrok),并创建一个指向
https://<your-host>/mcp的连接器。如果发现 URL 在隧道后显示错误的方案/主机,请设置:
export PUBLIC_BASE_URL=https://your-ngrok-host.example
Related MCP server: mcp-todo-demo
项目布局
路径 | 角色 |
| HTTP 路由器:OAuth 发现 + CORS + |
| 仅供开发的 OAuth 2.1 发现 + DCR/PKCE(生产环境请替换为真实的 IdP) |
| 用于聊天内 UI 的 Vite + React 源码 |
| 构建后的单文件 HTML(已忽略 git);由 |
架构与概念
一句话模型
ChatGPT 作为 MCP 客户端。它通过 HTTPS 上的 MCP 与您在 /mcp 上的 Node 服务器 通信。服务器注册 工具(模型可以调用的内容)和一个 资源(小部件的 HTML)。小部件运行在 iframe 中,并通过 postMessage 上的 JSON-RPC 网桥 与 ChatGPT 通信。同一源上的 OAuth 元数据允许 ChatGPT 附加连接器;它与 MCP 工具执行是分开的,但对于入驻是必需的。
模型上下文协议 (MCP)
MCP 是主机(ChatGPT)发现和调用服务器上的 工具 并读取 资源 的标准方式。此仓库使用 @modelcontextprotocol/sdk:一个 McpServer 实例注册功能,并连接到一个将 MCP 消息映射到 HTTP 的 传输层 (StreamableHTTPServerTransport)。
基础 MCP 与 Apps SDK 辅助工具
@modelcontextprotocol/sdk:核心McpServer、模式、传输层。@modelcontextprotocol/ext-apps:registerAppTool和registerAppResource用于规范化 UI 元数据(工具显示哪个 HTML 资源)并设置 Apps HTML MIME 类型 (RESOURCE_MIME_TYPE)。
小部件被注册为逻辑 URI(例如 ui://widget/todo.html)处的资源。该 URI 不需要是公共 Web URL;主机通过 MCP resources/read 解析它。每个工具的 _meta.ui.resourceUri 都指向同一个 URI,以便 ChatGPT 知道哪个 UI 界面属于哪个工具。
HTTP 前门 (server.js)
一个 Node http.Server 处理多个层面:
OAuth / 发现 (
oauth-dev.js) — ChatGPT 期望的知名 URL 和令牌端点。CORS
OPTIONS用于/mcp。健康检查
GET /。MCP
POST/GET/DELETE在/mcp上,通过可流式传输的 HTTP 传输层。404 用于未知路径。
因此,您拥有 一个进程,多个逻辑 HTTP API(OAuth HTTP + MCP HTTP)。
可流式传输的 HTTP 与服务器生命周期
传输层是为每个传入的 MCP 请求创建的,sessionIdGenerator: undefined(此演示为无状态模式)。每个请求都会构建一个新的 McpServer,并在响应关闭时销毁。
重要提示: 内存中的 todo 状态(server.js 中的 todos)存在于 模块作用域,而不是 McpServer 实例内部。因此,即使每个请求都获得一个新的 MCP 服务器对象,状态在 Node 进程的生命周期内仍然保持。
工具与 UI 契约
工具 (add_todo, complete_todo) 声明 输入模式 (Zod),以便主机验证参数。
工具结果包括:
content:模型/对话通常使用的 MCP 内容(例如文本)。structuredContent:小部件使用的 JSON — 这里是{ tasks: [...] }。
对每次变更使用相同的 structuredContent 形状,可以保持 React UI 同步,无论调用是由 小部件中的用户 触发,还是由聊天中的 模型 触发。
OAuth (oauth-dev.js)
ChatGPT 的连接器流程会获取 OAuth 受保护资源元数据 和 授权服务器元数据(参见 Apps SDK 认证)。如果没有这些路由,设置可能会失败,提示“获取 OAuth 配置时出错”。
此仓库提供了一个 仅供开发使用 的授权服务器(发现、动态客户端注册、授权重定向、PKCE 令牌交换),其范围限定为 ChatGPT 重定向 URL。请勿在生产环境中直接使用它 — 请替换为 Auth0、Stytch、Cognito 等,并在 MCP 请求上验证令牌。
当代理/ngrok 没有按您需要的方式设置 Host / X-Forwarded-Proto 时,PUBLIC_BASE_URL 会强制元数据中的公共 https:// 源。
小部件网桥 (widget/src/bridge.ts)
构建后的 HTML 运行在 ChatGPT 的 iframe 内部。它不像普通的 SPA 那样调用您的 /mcp URL;它使用 MCP Apps UI 网桥:
ui/initialize然后ui/notifications/initialized— 与主机握手。tools/call— 请求主机运行带有参数的命名 MCP 工具(与模型使用的工具相同)。ui/notifications/tool-result— 当 模型 运行工具时,主机可以推送结果,以便 UI 在没有来自tools/call的直接返回路径的情况下更新。
因此有 两条更新路径:UI 发起调用的 RPC 响应,以及模型发起调用的通知。
为什么使用单文件 HTML (Vite + vite-plugin-singlefile)
ChatGPT 从 MCP 资源读取中接收小部件作为 嵌入式 HTML,而不是作为“您的站点 + 独立的 JS 分块”。相对分块 URL 在该嵌入模型中会失效。构建过程产生 一个 dist/todo-widget.html,其中包含内联的 JS/CSS;server.js 在启动时将其读取到 todoHtml 中。
React 是一个 开发者工效学 层;可部署的工件 是静态 HTML。
端到端流程
ChatGPT 中的用户: 消息 → 模型选择工具 → ChatGPT POST 到您的 /mcp → 工具运行 → 返回 structuredContent.tasks → 主机显示/更新小部件。
小部件中的用户: React → 通过 postMessage 调用 tools/call → 主机转发到 MCP → 相同的处理程序 → RPC 结果更新状态。
连接器设置: ChatGPT 访问您源上的 /.well-known/... → 如果需要则进行 OAuth 链接 → 随后的 /mcp MCP 调用可能包含 Authorization: Bearer ...(在每个工具上强制执行该操作是生产步骤)。
自然的后续步骤
领域 | 方向 |
状态 | 将 todo 持久化到数据库中;按访问令牌中的已认证用户 ID 进行作用域划分。 |
认证 | 用真实的 IdP 替换 |
MCP 会话 | 如果您需要不同的流式传输或生命周期语义,请使用有状态会话。 |
工具 | 更丰富的描述/模式、可选的 |
小部件 | 相同的网桥;改进 UX、错误处理和加载状态。 |
脚本
脚本 | 描述 |
| 从 |
|
|
| 仅 Vite 构建 |
默认端口:8787 (PORT 环境变量可覆盖)。
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Build your own tools from chat: design, test and host them on a shareable MCP server URL.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA minimal MCP server demonstrating how to build ChatGPT-compatible applications using Next.js with widget rendering capabilities. Provides a starter template for integrating Next.js applications with the ChatGPT Apps SDK through the Model Context Protocol.-
- FlicenseNot gradedqualityDmaintenanceA minimal MCP server that provides an interactive to-do list with checkboxes in chat, demonstrating MCP Apps UI resource integration and tool-based state updates.-
- FlicenseNot gradedqualityDmaintenanceA minimal Next.js application demonstrating how to build an OpenAI Apps SDK compatible MCP server with widget rendering in ChatGPT.-
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server with a built-in OAuth 2.1 authorization server and a Next.js todo app, enabling authenticated task management (create, read, update, delete tasks) via natural language through an MCP client.7 npmISC