Skip to main content
Glama
TejasQ

CityJS London 2026 Companion

by TejasQ

Im Grunde, MCP Apps

Du weißt, wie MCP-Server Text, JSON und ähnliches zurückgeben? Nun, MCP Apps gehen noch einen Schritt weiter: Deine Tools können vollständige HTML-Widgets zurückgeben, die direkt in ChatGPT gerendert werden. Anstatt dass das Modell den Benutzer mit einer Wand aus JSON überschüttet, sieht dieser eine echte Benutzeroberfläche. Karten, Raster, Zeitpläne – was immer du willst.

Dies ist buchstäblich nur als POC gedacht und nichts allzu Ernstes. Es ist eine Begleit-App für die CityJS London 2026 Konferenz: Zeitplan, Referenten, Vortragssuche – alles wird als reichhaltiges, thematisch gestaltetes UI innerhalb von ChatGPT gerendert.

Ausführen

./start.sh

Das war's. Ein Befehl. Er installiert Abhängigkeiten, startet den Server, öffnet einen cloudflared-Tunnel und gibt dir eine URL, die du in ChatGPT einfügen kannst. Du benötigst Node.js 18+ und cloudflared (brew install cloudflared auf dem Mac).

Du wirst so etwas sehen:

  ┌─────────────────────────────────────────────────────────┐
  │                                                         │
  │   YOUR MCP ENDPOINT:                                    │
  │                                                         │
  │   https://something-random.trycloudflare.com/mcp        │
  │                                                         │
  │   NOW GO ADD IT TO CHATGPT:                             │
  │                                                         │
  │   1. Open chatgpt.com                                   │
  │   2. Click the tools icon (wrench) in the input bar     │
  │   3. Click 'Add MCP Server'                             │
  │   4. Paste the URL above                                │
  │   5. Ask: 'What's the CityJS London schedule?'          │
  │                                                         │
  └─────────────────────────────────────────────────────────┘

Frage dann ChatGPT Dinge wie "Zeig mir die Referenten" oder "Erzähl mir etwas über den Vortrag von Douglas Crockford" oder "Finde Vorträge über KI" und beobachte, wie die Widgets erscheinen.

Related MCP server: Hello Widget Example

Okay, aber wie lerne ich etwas über MCP Apps?

DER QUELLCODE IST NICHT BEÄNGSTIGEND! Geh ihn durch. Es gibt im Grunde 3 relevante Dateien (und sie sind klein!):

Datei

Was sie tut

server.js

Der MCP-Server. Registriert Widgets, registriert Tools, verbindet sie miteinander. Fang hier an.

widgets/schedule.html

Ein HTML-Widget, das eine Konferenz-Zeitachse rendert. Lies das <script>-Tag am Ende.

widgets/speakers.html

Ein HTML-Widget, das ein Raster mit Referentenkarten rendert. Gleiches Muster wie oben.

widgets/speaker-detail.html

Ein HTML-Widget für das vollständige Profil-Kärtchen eines einzelnen Referenten.

LIES SIE DIR DURCH. ES MACHT WIRKLICH SPASS!

Wie es im Grunde funktioniert

Eine MCP App ist einfach ein MCP-Server, der auch HTML-Widgets bereitstellt. Wenn ChatGPT dein Tool aufruft, rendert es dein Widget und leitet die Ausgabedaten des Tools hinein. Drei Dinge lassen dies geschehen:

1. Du schreibst ein HTML-Widget

Eine in sich geschlossene HTML-Datei mit eingebettetem CSS und JS. Sie empfängt Daten von ChatGPT und rendert sie. Das ist alles, was sie tut. Schau dir widgets/speakers.html an – es ist nur eine render(data)-Funktion und etwas CSS.

Das Widget empfängt Daten von ChatGPT wie folgt:

// ChatGPT puts tool output here when the widget loads
tryRender(window.openai?.toolOutput);

// Or fires this event slightly later
window.addEventListener("openai:set_globals", (e) => {
  tryRender(e.detail?.globals?.toolOutput);
});

Es übernimmt auch das Design (window.openai?.theme), sodass es automatisch zum Hell-/Dunkelmodus von ChatGPT passt.

2. Du registrierst das Widget als Ressource

In server.js teilst du dem MCP-Host mit: "Hey, ich habe dieses Widget":

server.registerResource(
  "schedule-widget",
  "ui://cityjs/schedule.html",
  { mimeType: "text/html;profile=mcp-app" },  // <-- this MIME type is the magic
  async () => ({
    contents: [{
      uri: "ui://cityjs/schedule.html",
      mimeType: "text/html;profile=mcp-app",
      text: scheduleWidgetHtml,  // the raw HTML string
    }],
  })
);

Der MIME-Typ text/html;profile=mcp-app ist das, was einen regulären MCP-Server in eine MCP-App verwandelt. Er sagt dem Host: "Dies ist ein renderbares Widget, nicht nur eine Datei."

3. Du bindest ein Tool an das Widget

Wenn du ein Tool registrierst, teilst du dem Host mit, welches Widget gerendert werden soll, wenn das Tool aufgerufen wird:

server.registerTool(
  "get_schedule",
  {
    title: "Get Schedule",
    description: "Get the CityJS London 2026 schedule...",
    inputSchema: { day: z.enum(["day1", "day2", "day3", "all"]).optional() },
    _meta: {
      ui: { resourceUri: SCHEDULE_URI },           // MCP spec way
      "openai/outputTemplate": SCHEDULE_URI,        // ChatGPT-specific way
    },
  },
  async ({ day }) => {
    return {
      structuredContent: { days },   // <-- your widget receives THIS
      content: [{ type: "text", text: JSON.stringify({ days }) }],  // fallback for non-UI hosts
    };
  }
);

structuredContent sind die Daten, die dein Widget rendert. content ist ein Text-Fallback für Hosts, die noch keine UI unterstützen (wie Claude). Gib immer beides zurück.

Und das ist im Grunde schon alles. Widget + Ressource + Tool-Bindung = MCP App.

Das Projekt

basically-mcp-apps/
  start.sh               <- run this. that's it.
  server.js              <- the MCP server. START READING HERE.
  package.json
  data/
    data.json            <- raw conference data (speakers, talks, bios)
    cityjs.js            <- enriches the raw data with rooms, types, etc.
  widgets/
    schedule.html        <- conference schedule timeline widget
    speakers.html        <- speaker grid widget
    speaker-detail.html  <- individual speaker profile card widget

Abhängigkeiten

Kein React, kein Build-Schritt, kein Bundler, kein Framework. Nur HTML-Dateien und ein Node-Server.

Viel Spaß beim Hacken!

F
license - not found
Not graded
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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
    Not graded
    maintenance
    A minimal ChatGPT app demonstrating interactive greeting widgets with confetti animations and theme support, built as a template for creating MCP servers with custom UI components.
  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server template integrated with the OpenAI Apps SDK for building ChatGPT-compatible widgets with automatic tool registration. It provides a suite of interactive UI components and ecommerce examples for creating type-safe, theme-aware widgets.
  • F
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that enables AI models to render GitHub's Primer React components directly within chat interfaces using a JSON component tree. It provides tools to list available components and display interactive UI elements with full GitHub theming support.

View all related MCP servers

Related MCP Connectors

  • MCP server for AI dialogue using various LLM models via AceDataCloud

  • Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.

  • Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only

View all MCP Connectors

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/TejasQ/basically-mcp-apps'

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