CityJS London 2026 Companion
基本上,MCP Apps
你知道 MCP 服务器是如何返回文本、JSON 等内容的吗?嗯,MCP Apps 更进一步:你的工具可以返回完整的 HTML 小部件,并直接在 ChatGPT 内部渲染。模型不再向用户倾倒一堆 JSON,而是看到一个实际的 UI。卡片、网格、时间轴——随你所想。
这仅仅是一个概念验证(POC),并不打算用于严肃场景。这是一个 CityJS London 2026 会议伴侣应用:日程安排、演讲者、演讲搜索——所有内容都作为丰富的主题 UI 在 ChatGPT 中渲染。
运行它
./start.sh就是这样。一条命令。它会安装依赖项、启动服务器、打开一个 cloudflared 隧道,并给你一个粘贴到 ChatGPT 中的 URL。你需要 Node.js 18+ 和 cloudflared(在 Mac 上使用 brew install cloudflared)。
你会看到类似这样的内容:
┌─────────────────────────────────────────────────────────┐
│ │
│ 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?' │
│ │
└─────────────────────────────────────────────────────────┘然后问 ChatGPT 一些问题,比如 "show me the speakers"(给我看看演讲者)、"tell me about Douglas Crockford's talk"(告诉我关于 Douglas Crockford 的演讲)或 "find talks about AI"(查找关于 AI 的演讲),然后看着小部件出现。
Related MCP server: Hello Widget Example
好吧,但我该如何学习 MCP Apps
源代码并不可怕!去看看吧。基本上只有 3 个相关文件(而且它们很小!):
文件 | 功能 |
MCP 服务器。注册小部件、注册工具、将它们绑定在一起。从这里开始。 | |
一个渲染会议时间轴的 HTML 小部件。阅读底部的 | |
一个渲染演讲者卡片网格的 HTML 小部件。模式与上面相同。 | |
用于单个演讲者完整资料卡片的 HTML 小部件。 |
去读读它们吧。真的很有趣!
它基本上是如何工作的
MCP App 只是一个同时也提供 HTML 小部件服务的 MCP 服务器。当 ChatGPT 调用你的工具时,它会渲染你的小部件并将工具的输出数据传入其中。三件事促成了这一点:
1. 你编写一个 HTML 小部件
一个包含内联 CSS 和 JS 的自包含 HTML 文件。它接收来自 ChatGPT 的数据并进行渲染。这就是它所做的全部工作。看看 widgets/speakers.html —— 它只是一个 render(data) 函数和一些 CSS。
小部件像这样从 ChatGPT 获取数据:
// 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);
});它还会获取主题(window.openai?.theme),以便自动匹配 ChatGPT 的浅色/深色模式。
2. 你将小部件注册为资源
在 server.js 中,你告诉 MCP 主机“嘿,我有这个小部件”:
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
}],
})
);MIME 类型 text/html;profile=mcp-app 是将常规 MCP 服务器转变为 MCP App 的关键。它告诉主机“这是一个可渲染的小部件,而不仅仅是一个文件”。
3. 你将工具绑定到小部件
当你注册一个工具时,你告诉主机在调用该工具时渲染哪个小部件:
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 是你的小部件渲染的数据。content 是为尚不支持 UI 的主机(如 Claude)提供的文本回退。请务必同时返回两者。
基本上就是这样。小部件 + 资源 + 工具绑定 = MCP App。
项目
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依赖项
@modelcontextprotocol/sdk-- MCP 服务器 SDKzod-- 输入模式验证cloudflared-- 将你的 localhost 隧道连接到互联网,以便 ChatGPT 可以访问它Node.js 18+
没有 React,没有构建步骤,没有打包器,没有框架。只有 HTML 文件和一个 Node 服务器。
Happy hacking!
This server cannot be installed
Maintenance
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
- 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 gradedqualityNot gradedmaintenanceA 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.
- FlicenseNot gradedqualityDmaintenanceAn 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.
- FlicenseNot gradedqualityBmaintenanceAn 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.
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
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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