Skip to main content
Glama

Демонстрация 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 default
  • MCP-эндпоинт: 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

Структура проекта

Путь

Роль

server.js

HTTP-маршрутизатор: обнаружение OAuth + CORS + MCP StreamableHTTPServerTransport на /mcp

oauth-dev.js

OAuth 2.1 обнаружение только для разработки + DCR/PKCE (замените на реальный IdP для продакшена)

widget/

Исходный код Vite + React для UI внутри чата

dist/todo-widget.html

Собранный однофайловый HTML (игнорируется git); загружается server.js при запуске


Архитектура и концепции

Модель в одном предложении

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 обрабатывает несколько поверхностей:

  1. OAuth / обнаружение (oauth-dev.js) — стандартные URL-адреса и эндпоинты токенов, которые ожидает ChatGPT.

  2. CORS OPTIONS для /mcp.

  3. Здоровье GET /.

  4. MCP POST / GET / DELETE на /mcp через потоковый HTTP-транспорт.

  5. 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:

  1. ui/initialize, затем ui/notifications/initialized — рукопожатие с хостом.

  2. tools/call — запрос к хосту на выполнение именованного инструмента MCP с аргументами (теми же инструментами, которые использует модель).

  3. 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 аутентифицированного пользователя из токена доступа.

Авторизация

Замените oauth-dev.js на реальный IdP; проверяйте издателя, аудиторию, области действия (scopes) в каждом запросе MCP.

Сессия MCP

Сессии с сохранением состояния, если вам нужна другая потоковая передача или семантика жизненного цикла.

Инструменты

Более богатые описания/схемы, опциональная outputSchema, более понятные имена для маршрутизации модели.

Виджет

Тот же мост; улучшение UX, ошибок и состояний загрузки.

Скрипты

Скрипт

Описание

npm run build

Сборка dist/todo-widget.html из widget/

npm start

npm run build, затем node server.js

npm run build:widget

Только сборка Vite

Порт по умолчанию: 8787 (переопределяется переменной окружения PORT).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A 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.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    A 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.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    A minimal Next.js application demonstrating how to build an OpenAI Apps SDK compatible MCP server with widget rendering in ChatGPT.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    A 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.
    18
    ISC

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/iamzeeali/mcpserver2'

If you have feedback or need assistance with the MCP directory API, please join our Discord server