Todo MCP Server
Демонстрация ChatGPT Todo MCP (Apps SDK + React)
Минималистичное приложение todo для ChatGPT: MCP-сервер предоставляет инструменты и интерактивный HTML-интерфейс, созданный с помощью React + Vite и упакованный в один файл. Включает небольшой слой dev OAuth, чтобы мастер настройки коннектора ChatGPT мог выполнить обнаружение.
Официальная справка: Apps SDK Quickstart.
Быстрый старт
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 + MCP |
| OAuth 2.1 обнаружение только для разработки + DCR/PKCE (замените на реальный IdP для продакшена) |
| Исходный код Vite + React для UI внутри чата |
| Собранный однофайловый HTML (игнорируется git); загружается |
Архитектура и концепции
Модель в одном предложении
ChatGPT выступает в роли MCP-клиента. Он общается по протоколу MCP поверх HTTPS с вашим Node-сервером по адресу /mcp. Сервер регистрирует инструменты (которые может вызывать модель) и ресурс (HTML для виджета). Виджет работает в iframe и общается с ChatGPT через JSON-RPC мост по postMessage. Метаданные 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-ресурс показать для инструмента) и устанавливают MIME-тип Apps HTML (RESOURCE_MIME_TYPE).
Виджет регистрируется как ресурс по логическому URI (например, ui://widget/todo.html). Этот URI не обязательно должен быть публичным веб-адресом; хост разрешает его через MCP resources/read. _meta.ui.resourceUri каждого инструмента указывает на тот же URI, чтобы ChatGPT знал, какая поверхность UI принадлежит какому инструменту.
HTTP-вход (server.js)
Один http.Server на Node обрабатывает несколько поверхностей:
OAuth / обнаружение (
oauth-dev.js) — стандартные URL-адреса и эндпоинты токенов, которые ожидает ChatGPT.CORS
OPTIONSдля/mcp.Здоровье
GET /.MCP
POST/GET/DELETEна/mcpчерез потоковый HTTP-транспорт.404 для неизвестных путей.
Таким образом, у вас один процесс, несколько логических HTTP API (OAuth HTTP + MCP HTTP).
Потоковый HTTP и время жизни сервера
Транспорт создается для каждого входящего запроса MCP с sessionIdGenerator: undefined (режим без сохранения состояния для этой демо-версии). Новый McpServer создается для каждого запроса и уничтожается при закрытии ответа.
Важно: состояние todo в памяти (todos в server.js) живет в области видимости модуля, а не внутри экземпляра McpServer. Поэтому состояние сохраняется в течение всего времени работы процесса Node, даже если каждый запрос получает новый объект MCP-сервера.
Инструменты и контракт UI
Инструменты (add_todo, complete_todo) объявляют входные схемы (Zod), чтобы хост проверял аргументы.
Результаты инструментов включают:
content: обычный контент MCP (например, текст) для модели/диалога.structuredContent: JSON, потребляемый виджетом — здесь{ tasks: [...] }.
Использование одной и той же структуры structuredContent для каждой мутации позволяет React UI оставаться синхронизированным, независимо от того, был ли вызов инициирован пользователем в виджете или моделью в чате.
OAuth (oauth-dev.js)
Поток коннектора ChatGPT получает метаданные защищенного ресурса OAuth и метаданные сервера авторизации (см. Apps SDK auth). Без этих маршрутов настройка может завершиться ошибкой «Error fetching OAuth configuration».
Этот репозиторий поставляется с сервером авторизации только для разработки (обнаружение, динамическая регистрация клиентов, перенаправление авторизации, обмен токенами PKCE), ограниченным URL-адресами перенаправления ChatGPT. Не используйте его в исходном виде для продакшена — замените на Auth0, Stytch, Cognito или аналогичные решения и проверяйте токены в запросах MCP.
PUBLIC_BASE_URL принудительно задает публичный источник https:// в метаданных, когда прокси/ngrok не устанавливают Host / X-Forwarded-Proto так, как вам нужно.
Мост виджета (widget/src/bridge.ts)
Собранный HTML работает внутри iframe ChatGPT. Он не вызывает ваш URL /mcp как обычное SPA; он использует мост MCP Apps UI:
ui/initialize, затемui/notifications/initialized— рукопожатие с хостом.tools/call— запрос к хосту на выполнение именованного инструмента MCP с аргументами (теми же инструментами, которые использует модель).ui/notifications/tool-result— когда модель запускает инструмент, хост может отправить результат, чтобы UI обновился без прямого обратного пути отtools/call.
Таким образом, существует два пути обновления: ответы RPC для вызовов, инициированных UI, и уведомления для вызовов, инициированных моделью.
Почему однофайловый HTML (Vite + vite-plugin-singlefile)
ChatGPT получает виджет как внедренный HTML из чтения ресурса MCP, а не как «ваш сайт + отдельные JS-чанки». Относительные URL-адреса чанков сломались бы в этой модели внедрения. Сборка создает один dist/todo-widget.html с инлайновым JS/CSS; server.js считывает его при запуске в todoHtml.
React — это слой эргономики разработчика; развертываемый артефакт — это статический HTML.
Сквозные потоки
Пользователь в ChatGPT: сообщение → модель выбирает инструмент → ChatGPT отправляет POST на ваш /mcp → инструмент выполняется → возвращает structuredContent.tasks → хост показывает/обновляет виджет.
Пользователь в виджете: React → tools/call через postMessage → хост пересылает в MCP → те же обработчики → результат RPC обновляет состояние.
Настройка коннектора: ChatGPT обращается к /.well-known/... на вашем источнике → связывание OAuth, если требуется → последующие вызовы MCP к /mcp могут включать Authorization: Bearer ... (принудительное применение этого для каждого инструмента — шаг для продакшена).
Естественные следующие шаги
Область | Направление |
Состояние | Сохраняйте задачи в базе данных; ограничивайте область видимости по ID аутентифицированного пользователя из токена доступа. |
Авторизация | Замените |
Сессия 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