全新操作系统?在 ChatGPT 中的应用和基于 MCP 的应用 SDK:解锁新平台

Blog image

作者:李博序,Macaron


介绍:

ChatGPT 中的应用现在允许第三方开发者构建在聊天界面内运行的互动小型应用程序。这些应用不再需要将用户引导至网站或移动应用,而是在对话中运行,并利用模型的推理来驱动操作。早期合作伙伴如 Canva、Coursera、Expedia 和 Zillow 已经展示了用户如何在不离开 ChatGPT 的情况下请求播放列表、设计海报或搜索房产[1]。新的Apps SDK建立在**Model Context Protocol (MCP)**之上,这是一种开放标准,允许模型与外部工具和用户界面交互[2]。这篇博客深入探讨了基于 MCP 的应用架构,解释了 SDK 的功能,逐步讲解了应用的构建过程,探索了用户如何发现和使用应用,并讨论了隐私和安全考量。我们引用官方文档和权威新闻报道,以确保分析的可信度。

理解模型上下文协议 (MCP)

为什么开放标准很重要

Model Context Protocol(模型上下文协议)」是应用程序 SDK 的基础。根据开发者文档,每个应用程序 SDK 集成都使用 MCP 服务器来公开工具、处理身份验证,并打包在 ChatGPT 中渲染的结构化数据和 HTML[2]。MCP 是一个开放标准——任何人都可以用任何语言实现服务器,并连接像 GPT-4 或 Codex 这样的模型。开源性质意味着没有供应商锁定;同一个应用理论上可以在任何实现该协议的 AI 平台上运行。这种开放性鼓励社区贡献,并促进了类似早期网络的生态系统,当时像 HTTP 这样的标准使网站能够实现互操作性。

服务器、工具和资源

MCP 服务器公开一个或多个工具。工具定义了模型可以调用的操作,例如“创建看板”、“搜索房屋”或“生成播放列表”。每个工具由一个机器名称、一个用户友好的标题和一个JSON 架构描述,该架构告诉模型它接受哪些参数。当 ChatGPT 决定应调用工具时,它会向服务器发送结构化调用。服务器执行逻辑——无论是通过查询 API、执行计算还是与数据库交互——然后返回一个工具响应。此响应包括三个字段:

  • structuredContent – 模型可见的数据,描述当前状态。例如,看板可能包含列和任务的数组[3]
  • content – 助手向用户反馈的可选文本。这可以总结结果或指导用户。
  • _meta – 模型不可见的隐藏元数据。开发人员使用它来存储 UI 组件中使用的 ID 或列表。例如,板的例子中使用了 tasksById 映射在 _meta 中,以维护任务细节而不暴露给模型[4]

工具还可以通过引用 ui:// URL 来引用资源,如 HTML 模板或图像。服务器在启动时注册这些资源。文档警告说,由于资源被 OpenAI 的基础设施缓存,开发人员应该通过在文件名中包含构建哈希来版本化它们[5]。否则,用户在部署后可能会看到过时的 UI。

结构化内容与元数据

区分 structuredContent 和 _meta 是至关重要的。根据文档,structuredContent 对模型可见,并用于填充 UI 组件;_meta 对模型隐藏,可能包含用于 UI 的额外数据,例如下拉菜单的列表[3]。通过分离可见数据和隐藏数据,开发人员可以在保护敏感信息的同时渲染丰富的界面。此设计还鼓励最小化数据共享;仅暴露完成任务所需的信息,符合隐私原则。

认证和会话

当用户首次调用应用时,服务器可能需要对其进行身份验证。Apps SDK 支持 OAuth 2.1 流程;开发者指定作用域并将用户重定向到身份提供者。一旦用户授权,应用获取令牌并可以访问用户的数据。服务器的任务是管理会话状态,通常通过将令牌存储在与用户 ChatGPT 账户相关的数据库中。这确保了后续工具调用可以重用会话,而无需再次提示用户。

安全原则

OpenAI 强调最小特权明确的用户许可深度防御[6]。应用程序应仅请求所需的最低权限,用户必须明确授权数据共享;模型本身不应猜测凭证。数据保留有限:结构化内容仅在用户的提示活动期间保留,日志在与开发者共享之前会被编辑[6]。应用组件的网络访问受到内容安全策略的限制;iframe 无法访问任意浏览器 API,所有 HTTP 请求必须从服务器而非客户端发出[7]。这可以防止跨站脚本和令牌泄露。

Apps SDK:在 ChatGPT 中构建真实应用

Blog image

开发者体验

Apps SDK 将 MCP 封装在惯用的客户端库(目前支持 Python 和 TypeScript)和脚手架工具中。创建应用时,你需要定义工具、注册 UI 模板并实现服务器逻辑。服务器可以在自己的基础设施上运行并使用任何框架(如 FastAPI、Express 等),但必须实现 MCP 端点。OpenAI 提供开发服务器和一个 MCP Inspector 用于本地测试调用。

开发者设计逻辑和用户界面。UI 通常用 React 编写并编译成静态资源。它们在 ChatGPT 中的沙盒 iframe 内提供服务。在这个 iframe 内,开发者可以访问全局 window.openai 对象与主机进行交互。根据 创建定制 UX 指南,此 API 提供:

  • 全局变量 - displayMode、maxHeight、theme 和 locale 提供组件关于布局和样式的信息[8]
  • 工具负载 - toolInput、toolOutput 和 widgetState 允许读取参数、结果和跨渲染的持久状态[8]
  • 操作 - setWidgetState() 保存跨消息持久的状态;callTool() 触发服务器操作;sendFollowupTurn() 发送后续提示给模型;requestDisplayMode() 请求全屏或画中画[8]
  • 事件 - 组件可以订阅 openai:set_globals,当主机更新布局或主题时,以及 openai:tool_response,当工具调用解决时[8]

这些 API 让开发者能够构建与模型推理保持同步的丰富交互组件。例如,如果用户在看板中将任务拖动到新的列,组件可以发送 callTool 更新服务器,持久化新状态,然后返回新的 structuredContent。同时,模型只会看到高级看板状态;UI 处理诸如拖放等细节。

注册工具和模板

In the server code you register a tool and its template. For instance, in a TypeScript server you might write:

import { Tool, StructuredToolResponse } from "@openai/apps";

// Register UI template
server.registerResource("ui://kanban-board/abc123", buildHtml());

// Define tool schema
const createBoard: Tool = {
  name: "createKanbanBoard",
  description: "Create a new kanban board with given tasks and columns",
  inputSchema: z.object({
    title: z.string(),
    columns: z.array(z.object({ name: z.string() })),
    tasks: z.array(z.object({ name: z.string(), columnIndex: z.number() }))
  }),
  async execute(input, ctx): Promise<StructuredToolResponse> {
    // compute board state
    const columns = input.columns.map((col, i) => ({
      id: i,
      title: col.name,
      taskIds: input.tasks.filter(t => t.columnIndex === i).map((_t, idx) => idx)
    }));
    const tasksById = input.tasks.map((task, id) => ({ id, name: task.name }));
    return {
      content: `Created board '${input.title}'`,
      structuredContent: { title: input.title, columns },
      _meta: { tasksById, uiTemplate: "ui://kanban-board/abc123" }
    };
  }
};

The _meta field includes tasksById for hidden metadata and uiTemplate referencing the registered HTML. When ChatGPT receives this response, it will render the template with the structured content. The window.openai.toolOutput object in the component can then read the board data and display it.

版本管理与缓存

由于像 UI 模板这样的资源会缓存到 OpenAI 的服务器上,开发者应在 ui:// 标识符中包含唯一的哈希或版本。文档警告说,如果部署新版本时没有更新路径,用户可能由于缓存而继续看到旧的 UI[5]。最佳实践是在 URL 中嵌入提交的 SHA 或构建 ID。这确保每次部署都会获取新的资源。

状态持久化与后续操作

组件通常需要持久化状态。例如,一个播放列表应用程序可能允许用户收藏歌曲;这些收藏的歌曲即使在用户询问其他问题时也应该保留。setWidgetState() 方法将数据存储在 structuredContent 外,并在会话轮次中持久化[8]。模型无法查看这些状态,从而确保隐私。

有时应用程序需要向用户询问澄清问题。sendFollowupTurn() 方法允许组件将新的提示发送回 ChatGPT,这样问题会出现在对话记录中,就像是模型提出的问题[8]。这对于多步骤工作流程非常有用:例如,一个旅行预订应用程序在用户选择酒店后可能会问“您会住几晚?”

Building Your First App: Step‑By‑Step Guide

In this section we will build a simple Task Tracker app that demonstrates the core concepts of the Apps SDK. The app will let a user create tasks and organise them into categories. We choose this example because it is generic, easy to extend and showcases structured content, metadata, custom UI and tool calls.

  1. Set up the MCP Server

First install the TypeScript SDK and scaffolding tool:

npm install -g @openai/apps-generator
apps init task-tracker
cd task-tracker
npm install

This command scaffolds a project with a server, a React frontend and build scripts. The server uses Express and the @openai/apps library. Run npm run dev to start the development server; the project includes an MCP Inspector that opens in your browser and simulates ChatGPT calling your app.

  • Define the Tool

Open src/server.ts and define a tool called createTasks. The tool accepts an array of tasks and returns structured content grouping them by category. It also provides a summary in the content field.

import { Tool, StructuredToolResponse } from "@openai/apps";



export const createTasks: Tool = {
  name: "createTasks",
  description: "Create a list of tasks grouped by category",
  inputSchema: z.object({ tasks: z.array(z.object({ name: z.string(), category: z.string() })) }),
  async execute({ tasks }): Promise<StructuredToolResponse> {
    const categories = Array.from(new Set(tasks.map(t => t.category)));
    const grouped = categories.map(category => ({
      name: category,
      taskIds: tasks.filter(t => t.category === category).map((_, i) => i)
    }));
    const tasksById = tasks.map((task, id) => ({ id, name: task.name, category: task.category }));
    return {
      content: `Created ${tasks.length} tasks in ${categories.length} categories`,
      structuredContent: { categories: grouped },
      _meta: { tasksById, uiTemplate: "ui://task-tracker/1.0.0" }
    };
  }
};

Register the template before using it:

server.registerResource("ui://task-tracker/1.0.0", fs.readFileSync(path.join(__dirname, "../dist/index.html"), "utf8"));
server.registerTool(createTasks);
  • Build the Custom UI

Next open src/frontend/App.tsx. This React component will read the structuredContent and display categories and tasks. It will also allow users to mark tasks as complete and persist that state using setWidgetState.

import { useEffect, useState } from "react";

declare global {
  interface Window {
    openai: any;
  }
}



export default function App() {
  const [complete, setComplete] = useState<{ [id: string]: boolean }>(() => window.openai.widgetState?.complete || {});
  const output = window.openai.toolOutput;
  const tasksById = output?._meta?.tasksById || [];
  const categories = output?.structuredContent?.categories || [];

  // persist completion state
  useEffect(() => {
    window.openai.setWidgetState({ complete });
  }, [complete]);

  return (
    <div className="task-tracker">
      {categories.map((cat: any, ci: number) => (
        <div key={ci} className="category">
          <h3>{cat.name}</h3>
          <ul>
            {cat.taskIds.map((tid: number) => (
              <li key={tid}>
                <label>
                  <input type="checkbox" checked={complete[tid]} onChange={() => setComplete(prev => ({ ...prev, [tid]: !prev[tid] }))} />
                  {tasksById[tid].name}
                </label>
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

This component uses window.openai.toolOutput to access the structuredContent and _meta fields. It stores completion state in widgetState so that checking a box persists even when the user continues the conversation. On subsequent tool calls, the component can fetch new tasks or update existing ones. This demonstrates how to combine model reasoning with client‑side interactions.

  • Testing and Iterating

Run npm run dev again and open the MCP Inspector. In the prompt area, type:

@task‑tracker create a list of tasks: buy milk in shopping, finish report in work, call mom in personal

The inspector will show the structured content and render the task list UI. You can check tasks off; the state persists across turns. You can then ask ChatGPT: “Remind me of my tasks later.” Because the model retains context, it can call the tool again, display the UI and summarise your progress.

How Users Discover and Use Apps

Blog image

Named Mention and In‑Conversation Discovery

ChatGPT surfaces apps when it believes they can assist the user. There are two primary discovery modes. Named mention occurs when the user explicitly mentions the app name at the beginning of a prompt; in this case, the app will be surfaced automatically[9]. For instance, “@Spotify create a workout playlist” immediately invokes the Spotify integration. The user must place the app name at the start; otherwise the assistant may treat it as part of the conversation.

对话中的发现发生在模型根据上下文推断出某个应用程序可能有帮助时。文档解释说,模型会评估对话上下文、先前工具的结果以及用户关联的应用程序,以确定哪个应用程序可能相关[9]。例如,如果您在讨论旅行计划,ChatGPT可能会建议使用Expedia应用程序来预订航班。算法使用工具描述和关键字等元数据来将对话与潜在操作匹配[10]。开发人员可以通过编写以行动为导向的描述和清晰的UI组件名称来提高发现率。

目录和启动器

OpenAI计划发布一个应用程序目录,用户可以在其中浏览和发现新应用程序[10]。每个列表将包括应用程序名称、描述、支持的提示和任何入门说明。用户还可以通过聊天中的“+”按钮访问启动器;这会显示一个基于上下文的可用应用程序菜单。这些入口点将帮助技术水平较低的用户在不需要记住名称的情况下找到并启用应用程序。

入门和同意

用户首次激活应用时,ChatGPT 会启动引导流程。模型会要求用户连接他们的账户(如果需要),并解释应用需要哪些数据。开发者指南强调,应用必须尊重用户隐私,行为可预测,并有明确的政策[11]。用户必须明确授予或拒绝权限;没有静默的数据访问。一旦连接,应用可以在后续互动中保持链接,但用户始终可以断开连接并撤销权限。

隐私、安全与负责任的设计

值得信赖的应用原则

OpenAI 的 应用程序开发者指南 定义了若干原则,以确保生态系统保持安全和可信。应用程序必须提供合法的服务,具备明确的隐私政策和数据保留实践,并遵循使用政策[11]。它们应尽量减少数据收集,避免存储敏感个人信息,并且未经用户同意不得分享用户数据[12]。应用程序必须表现得可预测,不能操控模型生成有害或误导性内容。

数据边界与最小化

指南强调,应用程序应仅收集其功能所必需的数据,不得请求或存储敏感数据,如健康记录或政府身份证件[12]。发送给模型的结构化内容不应包含机密信息;隐藏元数据不应存储用户令牌或私人详细信息。开发者必须对在OAuth过程中获得的任何令牌实施强加密和安全存储。服务器应保持用户会话之间的严格界限;一个用户的数据绝不能泄露到另一个用户的上下文中。

SDK 中的安全措施

安全与隐私指南》概述了平台内置的防御机制。它强调最小特权和明确的用户同意作为核心原则[6]。数据保留受到限制;开发者可访问的日志经过编辑以去除个人身份信息,结构化内容仅在提示需要时保留[6]。通过内容安全策略限制iframe内的网络访问;外部抓取必须通过服务器进行,以防止未经授权的跨域请求[7]。身份验证使用行业标准的OAuth流程,并采用短期令牌。开发者必须实施安全审查、漏洞报告渠道和事件监控,以保持运营准备[7]

公平性和适当性

应用程序必须适合广泛的受众。指南禁止提供长篇内容、复杂自动化或广告的应用程序[13]。例如,应用程序不应尝试在 ChatGPT 中提供 30 分钟的视频或复制整个社交网络。平台鼓励简洁的互动,以补充对话流程。违反规定可能导致拒绝或移除。

机会与考量

开发者的新分发渠道

通过向第三方应用程序开放 ChatGPT,OpenAI 将自己定位为用户和服务之间的“意图层”。开发者现在可以通过聊天界面接触到数百万用户,而无需构建单独的网页或移动应用程序。应用程序有潜力降低摩擦:用户无需下载应用或访问网站,只需在对话中提到服务即可。这可能使工具的使用更加民主化,并为小型开发者创造公平竞争环境。

早期合作展示了可能性:用户可以在观看 Coursera 课程时向 ChatGPT 提问;在 Canva 中设计海报;浏览 Expedia 旅行选项或 Zillow 房产列表;生成 Spotify 播放列表;或使用 Figma 绘制想法图[14][13]。由于应用程序在聊天中运行,模型可以总结、分析和生成建议,将静态内容转变为互动课程。应用程序还提供多种显示模式——内嵌卡片、全屏或画中画——为不同任务提供灵活性[15]

改变用户期望

无需切换上下文即可使用应用的能力可能会改变人们与服务互动的方式。ChatGPT不再仅仅是一个聊天机器人,而是一个意图的通用操作系统。正如Casey Newton所观察到的,这将使我们从启动独立应用转变为简单地陈述我们想要的内容[16]。一些分析师将这种转变比作App Store或浏览器的推出:一个聚合功能和竞争的平台。

然而,这种转变引发了关于控制和权力的问题。如果ChatGPT决定展示哪些应用,它可能会成为一个把关者。Newton警告说,基于用户偏好的“AI图谱”可能会带来比社交网络更严重的隐私风险[16]。经济激励可能导致应用的付费展示或排名。开发者可能会感到被迫为ChatGPT设计,而不是与用户直接建立关系。平台保持透明和公平对于维持信任至关重要。

监管和伦理影响

由于应用程序可以访问个人数据(如位置、联系人、支付方式),监管机构可能会仔细审查数据如何通过 ChatGPT 流动。尽管该平台尚未在欧盟上线,开发者仍需遵守 GDPR 等隐私法律[17]。OpenAI 承诺提供更细致的隐私控制和变现选项,包括允许在聊天中即时结账的代理商务协议[18]。该生态系统的成功将取决于强大的安全性、明确的用户同意和公平的经济模式。

未来方向与研究

Apps SDK 仍处于预览阶段,许多功能有待完善。开发者路线图包括:

  • 提交和审核流程 – 目前开发者可以开发应用,但无法公开列出。正式的审核流程将确保符合指南并建立信任。
  • 收入分享和货币化 – OpenAI 暗示了一种代理商协议,可能允许用户直接在聊天中购买商品[18]。这为电子商务带来了机遇,但也引发了关于费用、排名和竞争的问题。
  • 开发者工具 – 更多的语言和框架、改进的调试工具和更简单的部署流程将降低进入门槛。MCP 的开放标准性质可能导致社区驱动的实现和托管服务商的出现。
  • 互操作性 – 由于 MCP 是开放的,其他平台或模型可以采用。这可能会促成一个跨模型的应用生态系统,开发者可以一次编写,在任何地方运行。对标准化代理协议和上下文共享的研究将非常重要。
  • 安全研究 – 评估如何防止提示注入、恶意代码或用户数据滥用仍然是一个主要的研究领域。关于针对 LLM 集成应用的对抗性攻击的论文将为最佳实践和指南提供信息。

结论:新操作系统的诞生

引入ChatGPT中的应用基于MCP的应用SDK标志着我们与软件互动方式的重大转变。通过将第三方应用程序直接引入聊天界面,OpenAI创建了一个融合自然语言、推理和交互式用户界面的新平台。模型上下文协议提供了一种开放、标准化的方法,让模型可以调用工具和呈现组件;应用SDK通过处理服务器通信、UI集成和状态管理来简化开发。像任务跟踪器这样的逐步示例展示了如何在保持严格数据边界和隐私的同时轻松构建有用的应用程序。

然而,这项创新也带来了责任。开发者必须遵循优先考虑用户隐私、安全和公平的指南[11][12]。像最小权限和明确同意这样的安全机制保护用户[6]。同时,行业观察人士警告,该平台可能会创造新的门槛和隐私风险[16]。随着生态系统的成熟,透明性、开放标准和社区参与将决定ChatGPT的应用平台是否能成为日常任务的变革性、可信赖层。


[1] AI军备竞赛最新动态:ChatGPT 现允许用户在聊天中连接 Spotify 和 Zillow

https://www.forbes.com/sites/antoniopequenoiv/2025/10/06/openais-chatgpt-now-connects-with-third-party-apps-like-spotify-and-zillow-heres-the-latest-in-the-ai-arms-race/

[2] [3] [4] [5] 设置你的服务器

https://developers.openai.com/apps-sdk/build/mcp-server

[6] [7] 安全与隐私

https://developers.openai.com/apps-sdk/guides/security-privacy

[8] 构建自定义用户体验

https://developers.openai.com/apps-sdk/build/custom-ux

[9] [10] 用户互动

https://developers.openai.com/apps-sdk/concepts/user-interaction

[11] [12] 应用开发者指南

https://developers.openai.com/apps-sdk/app-developer-guidelines/

[13] ChatGPT 应用上线:这里是你可以尝试的首批应用 | The Verge

https://www.theverge.com/news/793081/chagpt-apps-sdk-spotify-zillow-openai

[14] OpenAI 开发者日 2025:ChatGPT 推出应用程序、开发者用的 AgentKit 和更便宜的 GPT 模型

https://indianexpress.com/article/technology/artificial-intelligence/openai-devday-2025-chatgpt-gets-apps-agentkit-for-developers-and-cheaper-gpt-models-10292443/

[15] OpenAI 宣布推出应用程序 SDK,允许 ChatGPT 启动和运行 Zillow、Canva、Spotify 等第三方应用程序 | VentureBeat

https://venturebeat.com/ai/openai-announces-apps-sdk-allowing-chatgpt-to-launch-and-run-third-party

[16] 新平台,熟悉的风险:Zillow 和 Expedia 押注于 OpenAI 的 ChatGPT 应用程序推出 – GeekWire

https://www.geekwire.com/2025/new-platform-familiar-risks-zillow-and-expedia-bet-on-openais-chatgpt-apps-rollout/

[17] OpenAI DevDay:ChatGPT 应用、AgentKit 和 Codex 的 GA 版本发布 - SD Times

https://sdtimes.com/ai/openai-devday-chatgpt-apps-agentkit-and-ga-release-of-codex/

[18] OpenAI 希望将 ChatGPT 打造成通用应用前端 - Ars Technica

https://arstechnica.com/ai/2025/10/openai-wants-to-make-chatgpt-into-a-universal-app-frontend/

毕业于埃默里大学,获得学士学位,并在美国生活和工作了十年。他曾先后就职于美国的私募股权和风险投资机构,后加入奇迹真基金的早期投资团队,从事AIGC和代理方向的长期研究。2025年,Macaron AI将与创始团队一同推出,致力于通过技术提升日常生活体验。

申请成为 Macaron 的首批朋友