Skip to main content
Glama

ChatGPT Todo MCP-Demo (Apps SDK + React)

Eine minimale Todo-App für ChatGPT: Ein MCP-Server stellt Tools und eine interaktive HTML-UI bereit, erstellt mit React + Vite und eingebettet als Single-File-Bundle. Enthält eine kleine Dev-OAuth-Schicht, damit der Connector-Assistent von ChatGPT die Erkennung abschließen kann.

Offizielle Referenz: Apps SDK Quickstart.

Schnellstart

npm install
npm start          # builds widget (prestart) then runs server on port 8787 by default
  • MCP-Endpunkt: http://localhost:8787/mcp

  • Für ChatGPT: Über HTTPS bereitstellen (z. B. ngrok) und einen Connector erstellen, der auf https://<your-host>/mcp zeigt.

  • Falls Discovery-URLs hinter einem Tunnel das falsche Schema/Host anzeigen, setzen Sie:

    export PUBLIC_BASE_URL=https://your-ngrok-host.example

Related MCP server: mcp-todo-demo

Projektstruktur

Pfad

Rolle

server.js

HTTP-Router: OAuth-Discovery + CORS + MCP StreamableHTTPServerTransport auf /mcp

oauth-dev.js

Dev-only OAuth 2.1 Discovery + DCR/PKCE (für Produktion durch einen echten IdP ersetzen)

widget/

Vite + React-Quellcode für die In-Chat-UI

dist/todo-widget.html

Erstelltes Single-File-HTML (gitignored); wird beim Start von server.js geladen


Architektur und Konzepte

Ein-Satz-Modell

ChatGPT fungiert als MCP-Client. Es spricht MCP über HTTPS mit Ihrem Node-Server unter /mcp. Der Server registriert Tools (was das Modell aufrufen kann) und eine Ressource (HTML für das Widget). Das Widget läuft in einem iframe und kommuniziert mit ChatGPT über eine JSON-RPC-Brücke mittels postMessage. OAuth-Metadaten auf demselben Ursprung ermöglichen es ChatGPT, den Connector anzubinden; dies ist von der MCP-Tool-Ausführung getrennt, aber für das Onboarding erforderlich.

Model Context Protocol (MCP)

MCP ist ein Standard für einen Host (ChatGPT), um Tools zu entdecken und aufzurufen sowie Ressourcen auf einem Server zu lesen. Dieses Repo verwendet @modelcontextprotocol/sdk: Eine McpServer-Instanz registriert Fähigkeiten und ist mit einem Transport verbunden, der MCP-Nachrichten auf HTTP abbildet (StreamableHTTPServerTransport).

Basis-MCP vs. Apps SDK-Helfer

  • @modelcontextprotocol/sdk: Kern-McpServer, Schemas, Transport.

  • @modelcontextprotocol/ext-apps: registerAppTool und registerAppResource normalisieren UI-Metadaten (welche HTML-Ressource für ein Tool angezeigt werden soll) und setzen den Apps-HTML-MIME-Typ (RESOURCE_MIME_TYPE).

Das Widget wird als Ressource unter einem logischen URI registriert (z. B. ui://widget/todo.html). Dieser URI muss keine öffentliche Web-URL sein; der Host löst ihn über MCP resources/read auf. Der _meta.ui.resourceUri jedes Tools zeigt auf denselben URI, damit ChatGPT weiß, welche UI-Oberfläche zu welchem Tool gehört.

HTTP-Eingang (server.js)

Ein Node http.Server bedient mehrere Oberflächen:

  1. OAuth / Discovery (oauth-dev.js) — bekannte URLs und Token-Endpunkte, die ChatGPT erwartet.

  2. CORS OPTIONS für /mcp.

  3. Health GET /.

  4. MCP POST / GET / DELETE auf /mcp über den streamfähigen HTTP-Transport.

  5. 404 für unbekannte Pfade.

Sie haben also einen Prozess, mehrere logische HTTP-APIs (OAuth HTTP + MCP HTTP).

Streamfähiges HTTP und Server-Lebensdauer

Der Transport wird pro eingehender MCP-Anfrage erstellt, mit sessionIdGenerator: undefined (zustandsloser Modus für diese Demo). Ein neuer McpServer wird pro Anfrage konstruiert und beim Schließen der Antwort wieder verworfen.

Wichtig: Der In-Memory-Todo-Zustand (todos in server.js) lebt im Modul-Scope, nicht innerhalb der McpServer-Instanz. Der Zustand bleibt also über die Lebensdauer des Node-Prozesses erhalten, auch wenn jede Anfrage ein neues MCP-Server-Objekt erhält.

Tools und der UI-Vertrag

Tools (add_todo, complete_todo) deklarieren Eingabeschemas (Zod), damit der Host die Argumente validiert.

Tool-Ergebnisse enthalten:

  • content: üblicher MCP-Inhalt (z. B. Text) für das Modell/die Konversation.

  • structuredContent: JSON, das vom Widget konsumiert wird — hier { tasks: [...] }.

Die Verwendung derselben structuredContent-Struktur für jede Mutation hält die React-UI synchron, egal ob der Aufruf durch den Benutzer im Widget oder durch das Modell im Chat ausgelöst wurde.

OAuth (oauth-dev.js)

Der Connector-Flow von ChatGPT ruft OAuth-geschützte Ressourcen-Metadaten und Autorisierungsserver-Metadaten ab (siehe Apps SDK Auth). Ohne diese Routen kann die Einrichtung mit „Error fetching OAuth configuration“ fehlschlagen.

Dieses Repo liefert einen Nur-für-Entwicklungszwecke-Autorisierungsserver (Discovery, dynamische Client-Registrierung, Authorize-Redirect, PKCE-Token-Austausch), der auf ChatGPT-Redirect-URLs beschränkt ist. Verwenden Sie ihn nicht unverändert für die Produktion — tauschen Sie ihn gegen Auth0, Stytch, Cognito oder ähnliches aus und verifizieren Sie Tokens bei MCP-Anfragen.

PUBLIC_BASE_URL erzwingt den öffentlichen https://-Ursprung in Metadaten, wenn Proxys/ngrok Host / X-Forwarded-Proto nicht wie gewünscht setzen.

Widget-Brücke (widget/src/bridge.ts)

Das erstellte HTML läuft innerhalb des iframes von ChatGPT. Es ruft Ihre /mcp-URL nicht wie eine normale SPA auf; es verwendet die MCP Apps UI-Brücke:

  1. ui/initialize dann ui/notifications/initialized — Handshake mit dem Host.

  2. tools/call — den Host bitten, ein benanntes MCP-Tool mit Argumenten auszuführen (dieselben Tools, die das Modell verwendet).

  3. ui/notifications/tool-result — wenn das Modell ein Tool ausführt, kann der Host das Ergebnis pushen, damit die UI aktualisiert wird, ohne einen direkten Rückgabepfad von tools/call.

Es gibt also zwei Update-Pfade: RPC-Antworten für UI-initiierte Aufrufe und Benachrichtigungen für Modell-initiierte Aufrufe.

Warum Single-File-HTML (Vite + vite-plugin-singlefile)

ChatGPT empfängt das Widget als eingebettetes HTML aus dem MCP-Ressourcen-Lesevorgang, nicht als „Ihre Website + separate JS-Chunks“. Relative Chunk-URLs würden in diesem Einbettungsmodell nicht funktionieren. Der Build erzeugt eine dist/todo-widget.html mit inlined JS/CSS; server.js liest sie beim Start in todoHtml ein.

React ist eine Entwickler-Ergonomie-Schicht; das bereitstellbare Artefakt ist statisches HTML.

End-to-End-Flows

Benutzer in ChatGPT: Nachricht → Modell wählt ein Tool → ChatGPT sendet POST an Ihr /mcp → Tool läuft → gibt structuredContent.tasks zurück → Host zeigt/aktualisiert das Widget.

Benutzer im Widget: React → tools/call via postMessage → Host leitet an MCP weiter → dieselben Handler → RPC-Ergebnis aktualisiert den Zustand.

Connector-Einrichtung: ChatGPT ruft /.well-known/... auf Ihrem Ursprung auf → OAuth-Verknüpfung falls erforderlich → nachfolgende MCP-Aufrufe an /mcp können Authorization: Bearer ... enthalten (dies bei jedem Tool zu erzwingen, ist ein Produktionsschritt).

Nächste Schritte

Bereich

Richtung

Zustand

Todos in einer Datenbank speichern; nach authentifizierter Benutzer-ID aus dem Access-Token filtern.

Auth

oauth-dev.js durch einen echten IdP ersetzen; Issuer, Audience und Scopes bei jeder MCP-Anfrage validieren.

MCP-Sitzung

Zustandsbehaftete Sitzungen, falls Sie andere Streaming- oder Lebenszyklus-Semantiken benötigen.

Tools

Reichhaltigere Beschreibungen/Schemas, optionales outputSchema, klarere Namen für das Modell-Routing.

Widget

Dieselbe Brücke; UX, Fehlerbehandlung und Ladezustände verbessern.

Skripte

Skript

Beschreibung

npm run build

Erstellt dist/todo-widget.html aus widget/

npm start

npm run build und dann node server.js

npm run build:widget

Nur Vite-Build

Standard-Port: 8787 (PORT-Umgebungsvariable überschreibt diesen).

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