Skip to main content
Glama

ChatGPT Todo MCPデモ (Apps SDK + React)

ChatGPT用の最小限のTodoアプリです。MCPサーバーがツールとインタラクティブなHTML UIを公開します。React + Viteで構築され、単一ファイルのバンドルとして埋め込まれています。ChatGPTのコネクタウィザードが検出を完了できるように、小規模な開発用OAuthレイヤーが含まれています。

公式リファレンス: Apps SDKクイックスタート

クイックスタート

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でのMCP StreamableHTTPServerTransport

oauth-dev.js

開発専用のOAuth 2.1検出 + DCR/PKCE(本番環境では実際のIdPに置き換えてください)

widget/

チャット内UI用のVite + Reactソース

dist/todo-widget.html

ビルド済みの単一ファイルHTML(gitignored); 起動時にserver.jsによって読み込まれます


アーキテクチャとコンセプト

一文でのモデル

ChatGPTはMCPクライアントとして機能します。/mcpにあるNodeサーバーHTTPS経由のMCPで通信します。サーバーはツール(モデルが呼び出せるもの)とリソース(ウィジェット用のHTML)を登録します。ウィジェットはiframe内で実行され、postMessageを介したJSON-RPCブリッジを通じてChatGPTと通信します。同じオリジン上のOAuthメタデータにより、ChatGPTはコネクタを接続できます。これはMCPツールの実行とは別ですが、オンボーディングには必須です。

Model Context Protocol (MCP)

MCPは、ホスト(ChatGPT)がサーバー上のツールを検出・呼び出し、リソースを読み取るための標準的な方法です。このリポジトリでは@modelcontextprotocol/sdkを使用しています。McpServerインスタンスが機能を登録し、MCPメッセージをHTTPにマッピングするトランスポートStreamableHTTPServerTransport)に接続されます。

Base 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)

1つのNode http.Serverが複数のサーフェスを処理します:

  1. OAuth / 検出 (oauth-dev.js) — ChatGPTが期待する既知のURLとトークンエンドポイント。

  2. CORS /mcp用のOPTIONS

  3. ヘルスチェック GET /

  4. MCP ストリーミング可能なHTTPトランスポートを介した/mcpへのPOST / GET / DELETE

  5. 404 不明なパス用。

つまり、1つのプロセス複数の論理HTTP API(OAuth HTTP + MCP HTTP)を扱います。

ストリーミング可能なHTTPとサーバーのライフタイム

トランスポートは受信したMCPリクエストごとに作成され、sessionIdGenerator: undefined(このデモではステートレスモード)が使用されます。リクエストごとに新しいMcpServerが構築され、レスポンスが閉じられると破棄されます。

重要: インメモリのTodo状態(server.js内のtodos)は、McpServerインスタンス内ではなく、モジュールスコープに存在します。そのため、各リクエストが新しいMCPサーバーオブジェクトを取得しても、Nodeプロセスのライフタイム中は状態が保持されます。

ツールとUIの契約

ツール(add_todocomplete_todo)は入力スキーマ(Zod)を宣言し、ホストが引数を検証できるようにします。

ツールの結果には以下が含まれます:

  • content: モデル/会話用の通常のMCPコンテンツ(テキストなど)。

  • structuredContent: ウィジェットが消費するJSON(ここでは{ tasks: [...] })。

すべての変更に対して同じstructuredContentの形状を使用することで、呼び出しがウィジェット内のユーザーによってトリガーされたか、チャット内のモデルによってトリガーされたかに関わらず、React UIを同期させることができます。

OAuth (oauth-dev.js)

ChatGPTのコネクタフローは、OAuth保護リソースメタデータ認可サーバーメタデータを取得します(Apps SDK認証を参照)。これらのルートがないと、セットアップ時に「OAuth設定の取得エラー」が発生する可能性があります。

このリポジトリには、ChatGPTのリダイレクトURLにスコープされた開発専用の認可サーバー(検出、動的クライアント登録、認可リダイレクト、PKCEトークン交換)が含まれています。本番環境でそのまま使用しないでください。Auth0、Stytch、Cognitoなどに置き換え、MCPリクエストでトークンを検証してください。

PUBLIC_BASE_URLは、プロキシやngrokがHost / X-Forwarded-Protoを期待通りに設定しない場合に、メタデータ内の公開https://オリジンを強制します。

ウィジェットブリッジ (widget/src/bridge.ts)

ビルドされたHTMLはChatGPTのiframe内で実行されます。通常のSPAのように/mcp URLを呼び出すのではなく、MCP Apps UIブリッジを使用します:

  1. ui/initialize その後に ui/notifications/initialized — ホストとのハンドシェイク。

  2. tools/call — 名前付きMCPツールを引数付きで実行するようホストに依頼(モデルが使用するものと同じツール)。

  3. ui/notifications/tool-resultモデルがツールを実行した際、ホストが結果をプッシュすることで、tools/callからの直接の戻りパスなしでUIを更新できます。

つまり、2つの更新パスがあります。UIが開始した呼び出しに対するRPCレスポンスと、モデルが開始した呼び出しに対する通知です。

なぜ単一ファイルHTMLなのか (Vite + vite-plugin-singlefile)

ChatGPTはウィジェットを「あなたのサイト + 個別のJSチャンク」としてではなく、MCPリソース読み取りからの埋め込みHTMLとして受け取ります。相対的なチャンクURLは、その埋め込みモデルでは機能しません。ビルドによって、JS/CSSがインライン化された1つdist/todo-widget.htmlが生成されます。server.jsは起動時にそれをtodoHtmlに読み込みます。

Reactは開発者の人間工学のためのレイヤーであり、デプロイ可能な成果物は静的なHTMLです。

エンドツーエンドのフロー

ChatGPTのユーザー: メッセージ → モデルがツールを選択 → ChatGPTがあなたの/mcpにPOST → ツールが実行 → structuredContent.tasksを返す → ホストがウィジェットを表示/更新。

ウィジェットのユーザー: React → postMessage経由でtools/call → ホストがMCPに転送 → 同じハンドラー → RPC結果が状態を更新。

コネクタ設定: ChatGPTがオリジンの/.well-known/...にアクセス → 必要に応じてOAuthリンク → その後の/mcpへのMCP呼び出しにはAuthorization: Bearer ...が含まれる場合があります(すべてのツールでこれを強制するのが本番ステップです)。

今後のステップ

エリア

方向性

状態

データベースにTodoを永続化し、アクセストークンから取得した認証済みユーザーIDでスコープ化する。

認証

oauth-dev.jsを実際のIdPに置き換え、各MCPリクエストで発行者、オーディエンス、スコープを検証する。

MCPセッション

異なるストリーミングやライフサイクルセマンティクスが必要な場合は、ステートフルなセッションを検討する。

ツール

より詳細な説明/スキーマ、オプションのoutputSchema、モデルルーティングのためのより明確な名前付け。

ウィジェット

同じブリッジを使用し、UX、エラー処理、読み込み状態を改善する。

スクリプト

スクリプト

説明

npm run build

widget/からdist/todo-widget.htmlをビルド

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